繁体   English   中英

减少大量二进制文件从硬盘读取访问时间的替代方法

[英]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. 读取文件的线程1 (“生产者”)。
  2. 线程2处理文件(“消费者”)。
  3. 它们之间的消息队列3

生产者以您已经在执行的方式读取文件,但是不处理它们,只是将它们排队到消息队列中。 使用者线程等待,直到它可以从队列中取出文件,对其进行处理,然后立即释放该文件已占用的内存,并继续等待队列。

如果可以通过从头到尾依次遍历它们来处理文件,则您甚至可以设计出更细粒度的“流”,在其中以块的形式读取和处理文件,这可以进一步降低峰值内存消耗(例如,如果您有一些超大文件,它们不再需要在内存中完整保存。


1或一组线程,用于并行化I / O(如果您预期从多个物理磁盘读取)。

2如果处理文件并不比读取文件便宜,则使用一组线程使CPU内核饱和。

3您不需要花哨的持久性分布式消息队列。 只是一个直接的内存队列,.NET中的a-la BlockingCollection (我相信您会在纯C语言中找到类似的东西)。

  1. 创建线程(循环)以将文件读入RAM。
  2. 处理RAM中单独线程中的数据,并在处理后释放RAM。
  3. 在互斥对象保护下,对共享对象中的文件(已读和已处理)进行限制和记录轮询。
  4. 将信号量用于资源(RAM中的文件)生产/利用同步。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM