是否可以使用线程来加速文件读取?

Mis*_*ère 17 c++ filesystems multithreading operating-system file

我想尽快读取文件(40k行)[编辑:其余的已经过时].

编辑:Andres Jaan Tack建议基于每个文件一个线程的解决方案,我想确定我得到了这个(因此这是最快的方式):

  • 每个条目文件一个线程将其整个读取并将其内容存储在相关的容器中( - >与条目文件一样多的容器)
  • 一个线程计算输入线程读取的每个单元格的线性组合,并将结果存储在退出容器中(与输出文件关联).
  • 一个线程按块(每4kB数据,大约10行)写入输出容器的内容.

我是否应该推断出我不能使用m-mapped文件(因为程序处于待机状态等待数据)?

先谢谢了.

此致

mystère先生.

And*_*ack 26

当你进一步询问时,你的问题会更深入一些.我会尝试涵盖你所有的选择......

一个文件:有多少个线程?

使用一个线程.

如果您直接从单个线程直接读取文件,操作系统将不会像您想的那样以小块的形式获取文件.相反,它会以巨大的(指数增长的)块预先获取文件,因此您几乎不会为进入磁盘而付出代价.你可能会等待磁盘几次,但一般来说它就像文件已经在内存中,这甚至无论如何mmap.

操作系统非常擅长这种顺序文件读取,因为它是可预测的.当你从多个线程中读取文件时,你实际上是随机读取的,这显然是不太可预测的.对于随机读取,预取器往往效率低得多,在这种情况下可能使整个应用程序变慢而不是更快.

注意:这甚至在您添加设置线程及其余所有内容的成本之前.这也需要花费一些成本,但与更多阻塞磁盘访问的成本相比,它基本上没什么用.

读取多个文件:有多少个线程?

使用与文件一样多的线程(或一些合理的数字).

为每个打开的文件单独完成文件预取.一旦开始阅读多个文件,您应该并行读取其中的几个文件.这是有效的,因为磁盘I/O调度程序将尝试找出读取所有这些内容的最快顺序.通常,操作系统和硬盘驱动器本身都有磁盘调度程序.同时,预取者仍然可以完成其工作.

并行读取多个文件总是比逐个读取文件更好.如果你确实一次读过一个,你的磁盘就会在预取之间闲置; 这是将更多数据读入内存的宝贵时间!唯一可能出错的方法是,如果内存太少,无法支持许多打开的文件; 那不常见了.

需要注意的一点是:如果您对多个文件读取过于过分,那么读取一个文件会开始将其他文件从内存中踢掉,然后您又回到了随机读取的状态.

n个文件合并为一个.

处理和生成多个线程的输出可能有效,但这取决于您需要如何组合它们.在任何情况下,你都必须要小心你如何同步线程,尽管肯定有一些相对简单的无锁方法可以做到这一点.

但要注意的一件事是:不要在小(<4K)块中写文件.打电话之前,一次至少收集4K数据write().此外,由于内核在您编写文件时会锁定文件,因此不要同时write()从所有线程调用; 他们都会互相等待,而不是处理更多的数据.

  • 并行读取文件并不高效 - RAM和硬盘之间只有一条总线.如果每次读取都需要搜索,那么您将增加读操作的开销. (2认同)

Ama*_*9MF 18

[编辑:原始问题是否启动最多40,000个线程会加快文件读取速度]

由于创建线程和上下文切换的开销,您建议的内容最有可能减慢访问速度.更多线程只有你自己才有帮助

1)计算限制,你有额外的核心,可以帮助工作

2)阻塞和其他线程可以在等待其他人解除阻塞时工作

3)你有一个非常聪明的算法,利用缓存行为

很可能你的速度受磁盘和/或内存带宽的限制而不是计算限制,因此单个执行线程可以最大限度地提高这些速度.