Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/143.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 多个小文件还是一个大文件?(或者,打开和关闭文件句柄的开销)(C+;+;)_C++_Optimization_File Io - Fatal编程技术网

C++ 多个小文件还是一个大文件?(或者,打开和关闭文件句柄的开销)(C+;+;)

C++ 多个小文件还是一个大文件?(或者,打开和关闭文件句柄的开销)(C+;+;),c++,optimization,file-io,C++,Optimization,File Io,我创建了一个应用程序,该应用程序执行以下操作: 进行一些计算,将计算出的数据写入文件-重复500000次(总的来说,一个接一个地写入500000个文件)-再重复2次(总的来说,写入了150万个文件) 读取文件中的数据,使用文件中的数据进行密集计算-重复1500000次迭代(迭代步骤1中编写的所有文件) 重复步骤2进行200次迭代 每个文件约212k,因此我总共有约300Gb的数据。在2.8 Ghz的Core 2 Duo CPU上,整个过程大约需要40天 我的问题是(正如你可能猜到的)完成整个过程

我创建了一个应用程序,该应用程序执行以下操作:

  • 进行一些计算,将计算出的数据写入文件-重复500000次(总的来说,一个接一个地写入500000个文件)-再重复2次(总的来说,写入了150万个文件)
  • 读取文件中的数据,使用文件中的数据进行密集计算-重复1500000次迭代(迭代步骤1中编写的所有文件)
  • 重复步骤2进行200次迭代
  • 每个文件约212k,因此我总共有约300Gb的数据。在2.8 Ghz的Core 2 Duo CPU上,整个过程大约需要40天

    我的问题是(正如你可能猜到的)完成整个过程所需的时间。所有的计算都是串行的(每个计算都依赖于之前的计算),因此我无法将此过程与不同的CPU或PC并行。我正在尝试思考如何使此过程更高效,并且我非常确定大部分开销都用于文件系统访问(duh…)。每次访问一个文件时,我都会打开它的句柄,然后在读取完数据后关闭它

    我改进运行时间的一个想法是使用一个300Gb的大文件(或者每个50Gb的几个大文件),然后我只使用一个打开的文件句柄,并简单地查找每个相关数据并读取它,但我不知道打开和关闭文件句柄的开销是多少。有人能解释一下吗

    我的另一个想法是尝试将文件分组为更大的~100Mb文件,然后每次读取100Mb,而不是多次读取212k,但这比上面的想法要复杂得多

    无论如何,如果有人能给我一些建议,或者有任何想法如何提高运行时间,我将不胜感激

    谢谢

    探查器更新:


    我在这个过程中运行了一个分析器,看起来计算占用了运行时间的62%,文件读取占用了34%。这意味着,即使我奇迹般地将文件i/o成本减少了34倍,我仍然有24天的时间,这是一个相当大的进步,但仍然需要很长的时间:)

    打开文件句柄不太可能成为瓶颈;实际磁盘IO为。如果您可以并行化磁盘访问(例如使用多个磁盘、更快的磁盘、一个RAM磁盘等),您可能会受益更多。另外,确保IO不会阻塞应用程序:从磁盘读取,并在等待IO时进行处理。例如,使用读卡器和处理器线程


    另一件事:如果下一步取决于当前的计算,那么为什么还要努力将其保存到磁盘?也许通过对流程依赖关系的另一种看法,您可以重新设计数据流并消除大量IO


    哦,是的,测量一下:)

    应该研究使用内存映射文件,因为它会减少系统调用的数量

    每个文件都是212k,所以我所有的 约300Gb的数据。看起来像是 整个过程大约需要40天…所有 计算是串行的(每个 计算取决于一个 之前),所以我无法与之相比 进程到不同的CPU或PC。。。漂亮的 当然大部分的开销都花在了 文件系统访问。。。每一个 当我访问一个文件时,我打开了一个句柄 然后在我完成后关闭它 读取数据

    串行写入300GB的数据可能需要40分钟,这只是40天的一小部分。磁盘写入性能在这里不应该是一个问题

    您只打开文件一次的想法是正确的。可能在每次操作后关闭文件会导致处理阻塞,直到磁盘完全写出所有数据,从而否定了磁盘缓存的好处


    我打赌这个应用程序的最快实现将使用内存映射文件,所有现代操作系统都具有此功能。它也可能成为最简单的代码。您需要一个64位处理器和操作系统,不需要300GB的RAM。一次将整个文件映射到地址空间,只需使用指针读取和写入数据。

    在进行任何更改之前,运行探查器跟踪可能会很有用,以确定大部分时间都花在哪里,以确保实际优化实际问题。

    如何使用?我想你可以只拿一张桌子就走。

    从你的简短解释来看,xtofl建议的线程是正确的方法。不过,我建议您首先评测应用程序,以确保时间在IO和cpu之间分配

    然后,我考虑三个线程由两个队列连接。< /P>

  • 线程1读取文件并将其加载到ram中,然后将数据/指针放入队列中。如果队列超过某个大小,线程将休眠;如果队列低于某个大小,线程将再次启动
  • 线程2从队列中读取数据并进行计算,然后将数据写入第二个队列
  • 线程3读取第二个队列并将数据写入磁盘
  • <>你可以考虑合并线程1和3,这可能会减少磁盘上的争用,因为你的应用程序每次只能做一个磁盘操作。
    操作系统如何处理所有文件?它们都在一个目录中吗?浏览目录(gui filemanager/dir/ls)时的性能如何?如果此性能不好,您可能在文件系统舒适区之外工作。虽然您只能在UNIX上更改此文件,但某些文件系统对不同类型的文件使用进行了优化,例如大文件、大量小文件等。您还可以考虑将文件分割到不同的目录。

    您是否考虑将其存储在数据库中?我已经考虑过了,但是这会使数据提取更快吗?您说您非常确定文件的打开/关闭是一个瓶颈。这是基于对程序进行分析的预感,还是更普遍的预感?如果