2

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

这种操作在每一行上独立发生。所以基本上,我正在寻找一些可以并行执行的功能。

void readFile(string filename){

  //do manipulation

}

操作可以并行发生。

同意这可以使用 hadoop 轻松完成,但这是一个矫枉过正的解决方案。(它的文件很大,但没有那么大,我需要 hadoop 来做这个......)

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

4

3 回答 3

6

我会为此使用mmap。mmap 使您可以像内存一样访问文件,因此您可以轻松地并行读取。请查看有关 mmap 的另一个 stackoverflow 主题。将非只读模式与 mmap 一起使用时要小心。

于 2013-06-21T21:00:13.690 回答
3

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

假设您在 ramdisk、非常快速的 raid 或其他东西上有这个,或者处理在某种程度上严重不平衡。无论哪种情况,线处理现在都占用了大部分时间。

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

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

我的“解决方案”是一个通用的高级设计,旨在激发您思考您可以使用哪些工具来适应您的需求。您必须仔细考虑才能使用它,这就是我想要的。

与任何线程操作一样,要非常小心地正确设计它,否则您将遇到竞争条件、数据损坏和各种痛苦。如果您能找到一个为您执行此操作的线程池/工作单元库,请务必使用它。

于 2013-06-21T23:17:47.710 回答
2

我建议您使用类似fread将许多行读入缓冲区然后并行操作缓冲区的方法。

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

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

由于您的文件太大,您可以在卡盘中读取它,并行操作该块,然后在下一个卡盘中读取。您甚至可以在并行处理前一个卡盘(例如 7 个线程)时读取下一个卡盘(使用一个线程),但您可能会发现这甚至没有必要。就个人而言,我会使用 OpenMP 进行并行处理。

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

于 2013-06-21T20:46:44.790 回答