MPI_Allgather我的代码瓶颈,我该如何解决?

时间:2013-02-27 04:17:31

标签: c++ c optimization mpi

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

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

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

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

如果这是原因,那么当测试通过时,我怎样才能与其他进程“交互”?这就是我想做的一切。换句话说,如果随机数通过测试,则向所有其他进程发送消息以停止他们正在做的事情,并将该数字添加到他们的数组中。

1 个答案:

答案 0 :(得分:0)

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

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

现在不知道依赖性,很难提出根本性的改进。假设没有命中,您可以考虑推测性地执行多次迭代,在您发现有命中之后丢弃无效的迭代。

除此之外,我建议MPI_AllreduceMAX一起确定需要添加的最高随机数。重复一遍,直到添加完所有。如果通常添加的次数很少,这显然效果很好。