0

我有一个程序,其目的是将特定数据添加到一个主数组。随机数测试passesTest(randomNumber)每秒执行数百万次,偶尔会通过测试并将随机数推到数组的末尾。所以大多数时候,当计算正在进行时,数组只是坐在那里。

我决定将这个过程与 MPI 并行化,因为我认为 1000 个处理器执行随机数测试将是一个很大的加速,并且由于内存写入非常罕见,因此 MPI 应该非常适合这项工作。令我沮丧的是,我的程序在mpirun -np 1我添加的每个进程中速度最快,但速度明显变慢。

while在包含 的循环结束时passesTest(randomNumber),我必须MPI::COMM_WORLD.Allgather()从每个进程中收集一个标志,该标志指示是否有一个新的随机数需要推送到数组中。如果有任何标志,true那么我执行另一个Allgather()实际收集这些数据并将其推送到每个进程的数组本地副本。同样,这一秒Allgather()很少执行,因为测试很少通过。

所以我猜测我的瓶颈是从每个 MPI 进程中收集所有标志以查看是否有新数据。每个随机数的测试执行速度很快,因此我假设由于从多个进程收集数据的开销,每秒数十亿次的 while 循环现在显着减少。这是一个很好的猜测吗?我是 MPI 的新手,所以我不知道涉及到什么样的时间尺度Allgather()

如果这是原因,那么我如何才能在通过测试时只与其他进程“交互”?这真的是我想做的。换句话说,如果一个随机数通过了测试,则向所有其他进程发送一条消息以停止它们正在执行的操作并将该数字添加到它们的数组中。

4

1 回答 1

0

首先,我强烈反对 Voo 和 Hristo Iliev 的评论。

从一个MPI_Allreduce开始检查通行证显然更快 - 它需要传输的数据少得多。但是 Allreduce 仍然需要 > 2 * log2(n) * latency。对于 1000 个进程,可能需要大约 100 微秒,具体取决于您的系统。如果您每秒进行数百万次测试,这意味着每次测试只需要 100 纳秒,那么很明显,每次测试后的集体操作确实会影响您的性能 - 无论每个单独的通信步骤设计得多么优化。

现在,在不了解依赖关系的情况下,很难提出根本性的改进。您可以考虑在没有命中的情况下推测性地执行多次迭代,在确定有命中后丢弃无效的迭代。

除此之外,我建议MPI_Allreduce确定MAX需要添加的最高随机数。重复此操作,直到添加所有内容。这显然只有在通常很少添加的情况下才有效。

于 2013-02-28T13:47:21.153 回答