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

3

我有一个很大的文本文件。我想读取这个文件并对其进行一些操作。

这些操作独立于每一行。因此,我正在寻找一些可以并行执行此操作的函数。

void readFile(string filename){

  //do manipulation

}

操作可以并行进行。

虽然可以使用 Hadoop 轻松实现此操作,但这是一个过度解决方案。(这是一个大文件,但不需要 Hadoop 处理...)

我该如何在 C++ 中实现这个操作?


8
在线程中读取数据,将其传递给其他线程。 - ctn
1
为每个线程创建一系列要读取的行,如果可能的话均匀分配。其余的只是使用语言特性来完成这个任务,你需要进行一些研究。 - dchhetri
1
你需要为线程创建一个工作队列:http://vichargrave.com/multithreaded-work-queue-in-c/ - ctn
10
由于最终速度受到磁盘访问速度的限制,因此在这方面投入过多的工作可能是没有意义的。如果您尝试从多个线程读取,由于竞争而导致性能下降。您可以使用生产者-消费者方法,但由于线程开销,可能无法获得所需的速度提升。 - Wug
2
然后你几乎没有任何处理。99.9%的时间用于从磁盘获取数据,而您无法使读取本身并行化。 - Guilherme Bernal
显示剩余3条评论
3个回答

7

1
虽然你可以并行读取,但按顺序读取可能会更快,因为它更加缓存友好。无论如何,如果没有适当的基准测试,你永远无法确定。 - Guilherme Bernal
当然这取决于情况。正如你所说,需要对正确的数据流进行基准测试。在某些情况下,mmap是一个相当不错的选择。了解它只会有好处。 - spinus

4
如果我面临这个问题并需要解决它,我会采用单线程的方法,因为没有必要在不加速底层介质的情况下投入过多的精力。
比方说你把这个放在一个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

我的“解决方案”是一个通用的、高级别的设计,旨在引发您思考什么工具可用于您可以根据自己的需求进行调整。您将不得不仔细考虑如何使用它,这也是我想要的。

与任何线程操作一样,非常谨慎地设计它,否则您将遇到竞争条件、数据损坏以及各种痛苦。如果您能找到一个为您完成此操作的线程池/工作单元库,请务必使用它。


3
我建议您使用类似于fread的方法将多行读入缓冲区,然后并行处理缓冲区。您可以在此处查看相关内容:http://www.cplusplus.com/reference/cstdio/fread/ 我曾经逐个像素(int)读取图像,进行像素转换,然后将值写入缓冲区。对于大文件,这需要超过1分钟的时间。但如果我先使用fread将整个文件读入缓冲区,然后在内存中对缓冲区进行转换,整个操作只需要不到一秒钟的时间。这是一个巨大的改进,而且没有使用任何并行处理。
由于您的文件非常大,您可以分块读取文件,在每个块上并行处理,然后读取下一个块。您甚至可以在并行处理前一个块(使用例如7个线程)的同时读取下一个块(使用一个线程),但您可能会发现这甚至不是必要的。个人建议使用OpenMP进行并行处理。
编辑:我忘记提到我给出了一个答案,建议使用fread读取文件,并使用OpenMP并行处理行。您可以在此处查看相关代码:openmp - while loop for text file reading and using a pipeline。对于您的需求,修改该代码可能非常简单。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接