遍历文件系统的最快方法

时间:2020-04-06 13:32:43

标签: c++ linux file filesystems hard-drive

有时候我需要递归地遍历一个文件夹,读取其中所有文件的内容。

我使用C ++和Linux。

文件夹的内容是任意的,从十亿个小文件到十二个庞大的文件。

试图达到最高的阅读速度,我陷入了困境。 一方面,从一个线程执行所有读取几乎总是更快,因为对文件系统的并行访问会导致同时读取的文件之间发生磁头抖动: enter image description here

另一方面,出于两个原因,从一个线程顺序访问文件系统的速度不如预期的快。

首先,在完成上一个读取请求和启动下一个读取请求之间花费的时间丢失了。我试图通过在读取线程中除了读取自身以外不执行任何操作来尽可能地减少它,但是在用户和内核空间之间不断切换仍然浪费了一些时间,尤其是在上述情况下数十亿个小文件。 enter image description here

第二,单线程读取不允许内核和/或HDD控制器对请求的扇区执行某些重新排序,这可以提高性能。

所以,我想实现两件事:

1)例如LibUsb,我可以有几个待处理的读取请求,这些请求将依次进行处理,但是在完成上一个请求和启动下一个请求之间没有暂停。 FS访问是否可以获得类似的东西?

enter image description here

2)是否可以同时向内核提交多个读取请求,以某种方式标记它们,以便内核知道这些请求没有个< / strong>截止日期,应将其累计执行的摘要时间降到最低?

enter image description here

1 个答案:

答案 0 :(得分:1)

由于您使用的是Linux,因此也许您应该尝试使用新的io_uring接口。与传统的同步(线程池+阻塞sycall)或异步 //assert.Equal(t, expectedOutput, buf.String()) if expectedOutput != buf.String() { t.Errorf("Failed! Expected %s - Actual: %s\n", expectedOutput, buf.String()) } 方法相比,它声称具有更高的效率和性能。

对于1,libaio的{​​{1}}标志似乎可以满足您的需求,只要您一直在请求中加注。