[英]Alternative to reduce large number of binary files reading access time from hard disk
在我的第一个应用程序原型中,我必须依次从硬盘读取大约40万个文件(每个4KB文件,总共约1.5 GB数据),并对从每个文件读取的数据进行一些操作,然后将结果存储在RAM中。 通过这种机制,我首先访问一个文件的I / O,然后利用CPU进行操作,然后继续访问另一个文件,但这过程非常缓慢。
要变通,现在我们首先读取所有文件,并将所有文件数据存储在RAM中,然后进行操作(利用CPU)。 它带来了显着的进步。
但是在开发的第二阶段,我必须读取20 GB的数据,现在我无法将其存储在RAM中。 而且,具有CPU利用率的单次读取操作非常耗时。
有人可以提出一些解决此问题的方法吗?
我正在Windows中使用Visual Studio编译器开发此应用程序。
有一种称为异步I / O(AIO)的技术,可让您在后台读取文件的同时继续对CPU进行一些处理。 您可以使用它在处理文件的同时读取接下来的几个文件。
各种AIO调用是特定于OS的。 在Windows上,Microsoft将其称为“重叠的I / O”。 请参阅此Wikipedia页面或此MSDN页面以获取更多信息。
要变通,现在我们首先读取所有文件,并将所有文件数据存储在RAM中,然后进行操作(利用CPU)。
(假设文件可以独立处理...)
你在那儿。 无需等待所有文件都已加载到RAM,而是在加载任何文件后立即开始处理。 那将是流水线的一种形式。
您将需要三个组件:
生产者以您已经在执行的方式读取文件,但是不处理它们,只是将它们排队到消息队列中。 使用者线程等待,直到它可以从队列中取出文件,对其进行处理,然后立即释放该文件已占用的内存,并继续等待队列。
如果可以通过从头到尾依次遍历它们来处理文件,则您甚至可以设计出更细粒度的“流”,在其中以块的形式读取和处理文件,这可以进一步降低峰值内存消耗(例如,如果您有一些超大文件,它们不再需要在内存中完整保存。
1或一组线程,用于并行化I / O(如果您预期从多个物理磁盘读取)。
2如果处理文件并不比读取文件便宜,则使用一组线程使CPU内核饱和。
3您不需要花哨的持久性分布式消息队列。 只是一个直接的内存队列,.NET中的a-la BlockingCollection (我相信您会在纯C语言中找到类似的东西)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.