如何在非常大的文本文件上直接有效地访问?

时间:2012-04-30 08:40:38

标签: c++ c file-io mpi

我有一个非常大的文本文件(+ 10GB),我想阅读一些数据挖掘技术。 为此,我使用MPI并行技术,因此许多进程可以一起访问同一个文件 实际上,我希望每个进程读取N行数。由于文件没有结构化(相同数量的字段,但每个字段可以包含不同数量的字符),我有义务解析文件,这是不平行的,需要花费很多时间。 有没有办法直接访问特定数量的行,并且需要解析和计算行数? 谢谢你的帮助。

3 个答案:

答案 0 :(得分:21)

如果您的文件没有以其他方式编入索引,则没有直接的方式。

索引它可能是值得的(扫描一次以找到所有行结尾,并存储每行或每行的偏移量)。如果您需要多次处理该文件,并且它不会更改,那么索引它的成本可能会因为使用该索引进行进一步运行而变得容易。

否则,如果您不需要所有作业完全相同数量的行/项目,您可以捏造它。
寻找给定的偏移量(比如1G),并寻找最近的行分隔符。在偏移2G等处重复,直到找到足够的断点。

然后,您可以在已识别的每个块上启动并行任务。

答案 1 :(得分:10)

除了此处提到的其他一些选项,不需要扫描整个文件:

  1. 创建一个主进程,通过管道/ fifos将行推送到执行实际处理的子进程。这可能有点慢,但如果说在子流程中花费的时间是实际的文本处理时间,那就应该没问题。

  2. 一个愚蠢但有效的技巧:假设您有N个进程,并且您可以通过argv告诉每个进程或者它是“序列号”,例如processor -serial_number [1|2|3...N] -num_procs N,他们都可以读取相同的数据,但只处理lineno % num_procs == serial_number行。它的效率有点低,因为它们都会读取整个数据,但是如果它们只能在每个第N行上运行,那就是大部分时间消耗的,那么你应该没问题。

答案 2 :(得分:4)

否则没有:在您不读取未知数据之前,没有人会知道有多少新行字符。这个问题的复杂性是O(n),因此意味着至少一次你必须阅读整个文件。然后,您可能希望构建一个索引表,在其中记录文件中有新行字符的位置:所有进程都可以使用它,并且使用fseek可以大大加快访问速度。