【发布时间】:2011-01-04 23:32:18
【问题描述】:
如何确保 MPI_Barrier 正确运行?测试方法是什么?
谢谢
【问题讨论】:
-
测试只能证明错误的存在,而不是它们的缺失。
如何确保 MPI_Barrier 正确运行?测试方法是什么?
谢谢
【问题讨论】:
我认为,要确保 MPI_Barrier 正常工作,您必须编写一个程序,保证工作和非工作障碍的行为不同。
我不认为@Neeraj 的回答一定会如此。如果屏障正常工作,则所有进程都将在写入第二个输出行之前写入它们的第一个输出行。但是,即使在没有障碍的情况下(或者如果您想这样想,障碍完全失效)也有可能发生这种情况。我的断言不依赖于他建议的非常短的睡眠时间(5msrank)。即使您假设进程等待(5srank),在没有障碍的情况下,语句也有可能以障碍强加的顺序出现。我不太可能授予您,但并非不可能,尤其是当您必须考虑 o/s 如何缓冲对 stdout 的多次写入时——您实际上可能正在测试该过程而不是障碍。 哦你哭了即使是最不准确的计算机时钟也会导致进程 1 等待的时间比进程 2 等待的时间要短,以显示屏障的正确工作。 如果 o/s抢先抢占处理器 1(进程 1 试图在哪个进程上运行)达 10 秒而不是。
依赖板载时钟进行同步实际上降低了程序的确定性。所有处理器都有自己的时钟,硬件不保证它们都以完全相同的速率或完全相同的滴答长度进行滴答。
该测试也没有充分探索屏障的所有失效模式。充其量它只探索完全的失败;如果实现实际上是一个泄漏的屏障,那么偶尔会有一个进程在最后一个进程到达屏障之前通过怎么办?一个错误在程序中非常常见。或者,屏障代码可能是 3 年前编写的,并且只有足够的内存来记录例如 2^12==4096 个进程的到来,而您已经将它放在具有 2^18 个处理器的全新机器上;屏障与其说是水坝,不如说是堰。
直到现在我还没有深入思考过这个问题,我从来没有怀疑过我使用的任何 MPI 实现都有错误的屏障,所以我没有关于如何彻底测试屏障的好建议。我倾向于使用并行调试器并通过屏障检查程序的执行情况,但这并不能保证正确的行为。
这是一个有趣的问题。
【讨论】:
#include <mpi.h>
int main (int argc , char *argv[])
{
int rank;
MPI_Init (&argc, &argv); /* starts MPI */
MPI_Comm_rank (MPI_COMM_WORLD, &rank); /* get current process id */
sleep(5*rank); // make sure each process waits for different amount of time
std::cout << "Synchronization point for:" << rank << std::endl ;
MPI_Barrier(MPI_COMM_WORLD) ;
std::cout << "After Synchronization, id:" << rank << std::endl ;
MPI_Finalize();
return 0;
}
【讨论】:
std::cout 不能有自己的障碍(MPI 或其他)吗?
Allen Downey 在他的书 The Little Book of Semaphores 中这样说(关于他提出的可重用屏障算法):
不幸的是,这个解决方案是 最不平凡的典型 同步代码:很难 以确保解决方案是正确的。 通常有一种微妙的方式 通过程序的特定路径 可能会导致错误。
更糟糕的是,测试一个 解决方案的实施不是 有很大帮助。错误很可能发生 很少因为特定的路径 这导致它可能需要一个 非常不幸的组合 情况。这样的错误几乎 无法重现和调试 常规手段。
唯一的选择是检查 仔细编码并“证明”它是 正确的。我把“证明”放在引号里 标记,因为我不是说, 必然地,你必须写一个 正式证明(虽然有 鼓励这种疯狂的狂热者)。
【讨论】: