【发布时间】:2014-12-10 10:04:26
【问题描述】:
我有一个 C++ 程序,我想在其中解析一个巨大的文件,寻找一些我已经实现的正则表达式。该程序在按顺序执行时运行正常,但后来我想使用 MPI 运行它。
我通过将 master(协调执行的那个)与 workers(并行解析文件的那个)区分开来开始适应 MPI。 主要功能。像这样的:
MPI::Init(argc, argv);
...
if(rank == 0) {
...
// Master sends initial and ending byte to every worker
for(int i = 1; i < total_workers; i++) {
array[0] = (i-1) * first_worker_file_part;
array[1] = i * first_worker_file_part;
MPI::COMM_WORLD.Send(array, 2, MPI::INT, i, 1);
}
}
if(rank != 0)
readDocument();
...
MPI::Finalize();
master 将向每个 worker 发送一个具有 2 个位置的数组,其中包含它将开始读取位置 0 中的文件的字节strong> 以及需要在 1 位置停止读取的字节。
readDocument() 函数现在看起来像这样(不是解析,只是每个 worker 读取他的文件部分):
void readDocument()
{
array = new int[2];
MPI::COMM_WORLD.Recv(array, 10, MPI::INT, 0, 1, status);
int read_length = array[1] - array[0];
char* buffer = new char [read_length];
if (infile)
{
infile.seekg(array[0]); // Start reading in supposed byte
infile.read(buffer, read_length);
}
}
我尝试了不同的示例,从将读取的输出写入文件到使用不同数量的进程运行它。例如,当我使用 20 个进程而不是 10 个进程运行程序时,会发生两次读取文件的时间。我预计会是将近一半的时间,但我不知道为什么会这样。
另外,在另一件事上,我想让 master 等待所有 workers 完成他们的执行,然后打印最后的时间。有没有办法在工人处理时“阻止”他?就像 C pthreads 中的 cond_wait?
【问题讨论】:
-
您是否将文件放在并行文件系统上?否则所有读取都将有效地全局锁定。慢 2 倍可能有点奇怪,但如果你真的耗尽资源,它可能会发生。
-
@luk32:我在本地运行程序,所有进程都在我的计算机中。该文件与可执行文件存储在同一文件夹中。有没有办法一次只由一个进程读取文件?如果是,我该如何解决?
-
@HighPerformanceMark 我不太明白这个问题,对不起。我如何知道从进程到磁盘有多少通道?
-
@gd.silva 好吧,简而言之,你不能,至少不容易。您是否同时访问文件甚至不是每个进程都无关紧要,因为如果它只是读取您肯定会耗尽HDD CPU带宽,并且添加进程只会增加开销。我的意思是,如果所有东西都在一个 HDD 上,那么它只有一个管道,操作系统必须管理对它的许多读取请求。
-
至于您的第二个问题,这与我提出的另一个问题完全不同——您为什么要这样做,让流程按照自己的甜蜜方式进行并获得最后一次有什么问题在你打电话给
mpi_finalize之后?