在C++中并行读取一个大型文本文件

Reading a large text file in parallel in C++

本文关键字:一个 大型 文本 文件 C++ 并行 读取      更新时间:2023-10-16

我有一个大的文本文件。。我想读取这个文件并在其中执行一些操作。

此操作在每一行上独立发生。所以,基本上,我在寻找一些可以做这种并行的函数。

void readFile(string filename){
  //do manipulation
}

这种操纵可以同时发生。

同意使用hadoop可以很容易地做到这一点,但这是一个过度的解决方案。(它的文件很大,但没有我需要hadoop的那么大…)

我如何在C++中做到这一点?

我会使用mmap。mmap为您提供了类似内存的文件访问权限,因此您可以轻松地并行读取。请看另一个关于mmap的stackoverflow话题。使用mmap使用非只读模式时要小心。

如果我要面对这个问题并必须解决它,我只会使用单线程方法,在不加快底层介质速度的情况下投入太多精力是不值得的。

假设你在ramdisk上有这个,或者一个非常快速的突袭,或者其他什么,或者处理在某种程度上是巨大的不平衡。不管在什么情况下,行处理现在都占用了大部分时间。

我会这样构建我的解决方案:

class ThreadPool; // encapsulates a set of threads
class WorkUnitPool; // encapsulates a set of threadsafe work unit queues
class ReadableFile; // an interface to a file that can be read from
ThreadPool pool;
WorkUnitPool workunits;
ReadableFile file;
pool.Attach(workunits); // bind threads to (initially empty) work unit pool
file.Open("input.file")
while (!file.IsAtEOF()) workunits.Add(ReadLineFrom(file));
pool.Wait(); // wait for all of the threads to finish processing work units

我的"解决方案"是一个通用的、高级别的设计,旨在激发人们对您可以使用哪些工具来适应您的需求的思考。你必须仔细思考才能使用这个,这正是我想要的。

与任何线程操作一样,要非常小心地正确设计它,否则您将遇到竞争条件、数据损坏和各种痛苦。如果你能找到一个线程池/工作单元库来为你做这件事,那么一定要使用它。

我建议您使用类似fread的东西将许多行读取到缓冲区中,然后对缓冲区进行并行操作。

http://www.cplusplus.com/reference/cstdio/fread/

我曾经一次读取一个图像一个像素(int),对像素进行转换,然后将值写入缓冲区。对于一个大文件来说,这花了1分钟多的时间。当我使用fread先将整个文件读取到缓冲区中,然后对内存中的缓冲区进行转换时,整个操作只花了不到一秒钟的时间。在不使用任何并行性的情况下,这是一个巨大的改进。

由于你的文件太大了,你可以在chuck中读取它,所以并行地对chunk进行操作,然后在下一个chuck中进行读取。当你并行处理上一个卡盘(例如7个线程)时,你甚至可以读取下一个夹头(有一个线程),但你可能会发现这根本没有必要。就我个人而言,我会与OpenMP进行并行处理。

编辑:我忘了提到我给出了使用fread读取文件并与OpenMP并行处理行的答案openmp-while循环用于文本文件读取和使用管道修改代码以执行您想要执行的操作可能很简单。