MPI:rand() 在每次运行中为所有进程提供相同的常数

Posted

技术标签:

【中文标题】MPI:rand() 在每次运行中为所有进程提供相同的常数【英文标题】:MPI: rand() gives the same constant numbers across all processes in every run 【发布时间】:2014-05-19 16:14:07 【问题描述】:

我想问一个关于 (Open)MPI 上下文中的 rand() 的问题。我们在并行编程课程中获得了一个实现任务——创建一个 MPI 应用程序,其中所有参与者进程都选择一个领导者(随机地——他们必须“投票”)。我的程序如下所示:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <limits.h>
#include <mpi.h>

int main (int argc, char *argv[]) 
    int rank, size, vote, result;

    MPI_Init(&argc, &argv);

    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);

    vote = rand(); // Each process' vote.
    printf("%d: %d\n",rank+1, vote); // Only for debugging purposes here.

    MPI_Allreduce(&vote, &result, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
    result = (result & INT_MAX) % size + 1; // Select the leader.

    printf("Process %*d/%d: %d is the leader.\n", (int)(ceil(log10(size+1))), rank+1, size, result);

    MPI_Finalize();
    return 0;

问题是,当我使用OpenMPI1.6编译和运行它时,无论程序启动多少个进程,每个进程的投票都是1804289383。在程序的每次新运行中,该数字始终相同。因此,如果我运行 mpirun -np 7 ./a.out,领导者总是 5,如果我用 -np 8 运行它,第一个进程总是领导者,依此类推......

谁能解释一下我做错了什么以及如何解决这个问题?

非常感谢。

【问题讨论】:

只需使用适当的 PRNG 并为其提供每个进程的种子。 rand 非常糟糕,即使是播种。 @CodesInChaos rand 不好,但不是“在后续运行中在不同进程上生成相同的序列”不好。它非常适合手头的任务,解决 OP 问题的单行代码比导入任何第三方 RNG 可能要容易得多。 【参考方案1】:

你必须播种你的随机数生成器,例如

srand(time(NULL) + rank);

【讨论】:

哦,天哪,谢谢...这是一个非常愚蠢的错误。 你需要为每个进程使用不同的种子,所以要小心【参考方案2】:

您没有为随机函数提供种子。 “通常”的种子是time(NULL),尽管您可能想检查一些更灵活的东西,比如 Mersenne Twister。

A good random number generator for C

【讨论】:

以上是关于MPI:rand() 在每次运行中为所有进程提供相同的常数的主要内容,如果未能解决你的问题,请参考以下文章

mpi 进程在信号 11 上退出

使用 MPI 终止所有进程

如何在 C# 中为多个进程提供单个命令窗口

MPI_Rank 为所有进程返回相同的进程号

为啥我所有的开放 MPI 进程的排名都是 0?

验证远程主机以运行 ms-mpi 进程