我想尽可能快地读取文件(40k 行)[编辑:其余已过时]。
编辑:Andres Jaan Tack 建议了一个基于每个文件一个线程的解决方案,我想确定我得到了这个(因此这是最快的方法):
- 每个条目文件一个线程读取整个文件并将其内容存储在关联的容器中(-> 与条目文件一样多的容器)
- 一个线程计算输入线程读取的每个单元格的线性组合,并将结果存储在导出容器(与输出文件相关联)中。
- 一个线程按 block (每 4kB 数据,大约 10 行)写入输出容器的内容。
我应该推断我不能使用m映射文件(因为程序处于待机等待数据)?
先谢谢了。
此致,
神秘先生。
最佳答案
当您进一步询问时,您的问题变得更深入了。我会尽量涵盖你所有的选择......
读取一个文件:有多少线程?
使用一个线程。
如果您从单个线程从前到后直接读取文件,操作系统将不会像您想的那样以小块的形式获取文件。相反,它会预取你前面的文件,以巨大的(指数增长的) block 的形式出现,所以你几乎不会因为去磁盘而付出代价。您可能会等待磁盘几次,但通常它就像文件已经在内存中一样,这甚至与 mmap
无关。
操作系统非常擅长这种顺序文件读取,因为它是可预测的。当您从多个线程读取文件时,您实际上是在随机读取,这(显然)不太可预测。对于随机读取,预取器往往效率低得多,在这种情况下,可能会使整个应用程序变慢而不是更快。
注意:这甚至是在您添加设置线程和所有其余部分的成本之前。这也需要一些成本,但与更多阻塞磁盘访问的成本相比,这基本上不算什么。
读取多个文件:多少线程?
使用尽可能多的线程(或一些合理的数量)。
为每个打开的文件单独进行文件预取。一旦开始读取多个文件,您应该同时读取其中的几个文件。这是因为磁盘 I/O Scheduler将尝试找出读取所有这些文件的最快顺序。通常,操作系统和硬盘驱动器本身都有一个磁盘调度程序。同时,预取器仍然可以完成它的工作。
并行读取多个文件总是比逐个读取文件更好。如果您确实一次读取它们,那么您的磁盘将在预取之间空闲;这是将更多数据读入内存的宝贵时间!唯一可能出错的方法是您的 RAM 太少而无法支持许多打开的文件;这已经不常见了。
请注意:如果您过于热衷于读取多个文件,读取一个文件将开始从内存中踢出其他文件的位,并且您会回到随机读取的情况。
将 n 个文件合并为一个。
从多个线程处理和生成输出可能会起作用,但这取决于您需要如何组合它们。在任何情况下,您都必须小心同步线程的方式,尽管肯定有一些相对简单的无锁方法可以做到这一点。
不过,有一点需要注意:不要费心将文件写入小 (< 4K) block 。在调用 write()
之前,一次至少收集 4K 的数据。此外,由于内核会在您编写文件时锁定文件,因此不要从所有线程中同时调用 write()
;他们都会互相等待,而不是处理更多数据。
关于c++ - 是否可以使用线程来加快文件读取速度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3054442/