Coo*_*der 6 c++ multithreading file
我的应用程序使用文本文件将数据存储到文件中.我正在测试通过多线程操作来读取它的最快方法.我使用了以下两种技术:
使用与NUMBER_OF_PROCESSORS环境变量一样多的流.每个流都在不同的线程上.为每个流平均分配文件中的行总数.解析文本.
只有一个流解析整个文件并将数据加载到内存中.创建线程(= NUMBER_OF_PROCESSORS - 1)以解析内存中的数据.
测试在各种文件大小100kB - 800MB上运行.文件中的数据:
100.23123 -42343.342555 ...(and so on)
4928340 -93240.2 349 ...
...
Run Code Online (Sandbox Code Playgroud)
数据存储在2D数组中double.
结果:两种方法在解析文件时花费大致相同的时间.
问题:我应该选择哪种方法?
方法1对硬盘不利,因为多个读取访问同时在随机位置执行.
方法2很糟糕,因为所需的内存与文件大小成正比.这可以通过将容器限制为固定大小,删除已解析的内容并从阅读器再次填充来部分克服.但这会增加处理时间.
方法 2 存在顺序瓶颈(单线程读取和分发工作项)。根据阿姆达尔定律,这不会无限期地扩展。不过,这是一种非常公平和可靠的方法。
方法 1 没有瓶颈并且可以扩展。确保不要造成磁盘上的随机IO。我会使用互斥体一次只读取一个线程。读取大约 4-16MB 的大连续块。在磁盘进行单头寻道时,它可以读取大约 1MB 的数据。
如果解析这些行需要相当长的时间,则不能使用方法 2,因为连续部分很大。它不会扩展。不过,如果解析速度很快,请使用方法 2,因为它更容易正确。
为了说明瓶颈的概念:想象一下 1.000.000 个计算线程要求一个读取器线程为它们提供行。该读者线程将无法按照要求的速度继续分发行。您不会获得 1e6 倍的吞吐量。这无法扩展。但是,如果 1e6 个线程独立于非常快的 IO 设备进行读取,您将获得 1e6 倍的吞吐量,因为不存在瓶颈。(我用了极端的数字来说明这一点。同样的想法也适用于小事。)