我想尽可能快地读取一个文件(40k行)编辑:其余的都过时了。
编辑: Andres Jaan Tack建议了一个基于每个文件一个线程的解决方案,我想确保我得到了这个(因此这是最快的方法):
我是否应该推断我不能使用m映射文件(因为程序处于待机状态等待数据)?
事先谢谢你。
由衷地,
mystère先生
发布于 2010-06-17 01:00:30
当你进一步问的时候,你的问题变得更深了一点。我会试着覆盖你所有的选择..。
读取一个文件:有多少个线程?
使用一个线程。
如果您从单个线程从前到后直接读取文件,操作系统将不会像您所想的那样以小块的形式获取文件。相反,它将以巨大的(指数级增长的)块在您之前预取文件,因此您几乎不会为访问磁盘而付出任何代价。您可能会等待磁盘几次,但通常情况下,它会像文件已经在内存中,这甚至与mmap
无关。
操作系统非常擅长这种顺序文件读取,因为它是可预测的。当你从多个线程读取一个文件时,你本质上是随机读取的,这(显然)是不可预测的。预取器对随机读取的效率往往要低得多,在这种情况下,可能会使整个应用程序变得更慢,而不是更快。
注意:这甚至是在你加上设置线程和所有其他东西的成本之前。这也需要一些成本,但与更多阻塞磁盘访问的成本相比,这基本上算不了什么。
读取多个文件:有多少线程?
使用尽可能多的线程和你拥有的文件(或者一些合理的数量)。
为每个打开的文件单独执行文件预取。一旦开始读取多个文件,就应该并行读取其中的几个文件。这之所以有效,是因为磁盘I/O Scheduler将尝试找出读取所有数据的最快顺序。通常,在操作系统和硬盘驱动器本身上都有一个磁盘调度程序。同时,预取器仍然可以执行它的工作。
并行读取多个文件总是比逐个读取文件要好。如果您一次只读取一个,那么您的磁盘将在两次预取之间空闲;这是将更多数据读入内存的宝贵时间!唯一可能出错的地方是RAM太少,无法支持许多打开的文件;这种情况已经不常见了。
需要注意的是:如果您过于热衷于多次读取文件,读取一个文件将开始将其他文件的一小部分从内存中踢出,并且您又回到了随机读取的情况。
将n个文件合并为一个文件。
处理和产生来自多个线程的输出可能是可行的,但这取决于您需要如何组合它们。在任何情况下,您都必须小心如何同步线程,尽管肯定有一些相对简单的无锁方法可以做到这一点。
不过,有一件事需要注意:不要费心将文件写成小块(< 4K)。在调用write()
之前,一次收集至少4K的数据。此外,由于内核将在您写入文件时锁定该文件,因此不要从所有线程一起调用write()
;它们将彼此等待,而不是处理更多数据。
发布于 2010-06-16 22:59:17
编辑:最初的问题是启动多达40,000个线程是否会加快文件读取速度
您的建议很可能会由于创建线程和上下文切换的开销而减慢访问速度。更多的线程只有在你
1)计算受限,并且您有额外的内核可以帮助您完成工作
2)阻塞和其他线程可以工作,同时等待其他线程解除阻塞
3)你有一个非常聪明的算法,它利用了缓存行为
你的速度很可能受到磁盘和/或内存带宽的限制,而不是计算限制,因此单个执行线程将能够最大限度地提高速度。
发布于 2010-06-16 23:00:51
是的,这是浪费时间。在最好的情况下,您最终将获得大致相同的性能。在最坏的情况下,这可能会损害从磁盘寻道到文件的不同部分而不是连续读取文件的性能。
https://stackoverflow.com/questions/3054442
复制相似问题