MPI, C - Невозможно правильно генерировать случайные числа - PullRequest
0 голосов
/ 03 октября 2018

Привет, я новичок в Stackoverflow.
Я использую MPI в C. Я запускаю 10 процессов.

Каждый из моих процессов содержит генератор случайных чисел, который уникальным образом генерирует случайное число (0 или 1) для этого процесса.

Однако, когда я запускаю свой код, я обнаружил, что процессы счетные ранги (такие как ранг 0 или ранг 2 или ранг 4) назначаются только случайным числам 0. Только 0.
Между тем, процессы с нечетными рангами (например, ранг 1 или ранг 3 или ранг 4) являются тольконазначил случайное число 1.

Как мне изменить мой код так, чтобы некоторым четным процессам можно было присвоить случайное число 1, а некоторым нечетным процессам - случайное число 0?

Вот мой код:

#include <mpi.h>
#include <stdio.h>

int main(int argc, char** argv) {
    // Initialize the MPI environment
    MPI_Init(NULL, NULL);

    // Get the number of processes
    int world_size;
    MPI_Comm_size(MPI_COMM_WORLD, &world_size);

    // Get the rank of the process
    int world_rank;
    MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);

    //try to generate unique random number 
    srand(time(NULL)+world_rank);
    int rando =  rand()%2;
    // Print off rank with random number
    printf("Rank %d has the random value %d\n", world_rank, rando);

    // Finalize the MPI environment.
    MPI_Finalize();
}

Вот мой вывод:

Rank 0 has the random value 0
Rank 7 has the random value 1
Rank 8 has the random value 0
Rank 9 has the random value 1
Rank 1 has the random value 1
Rank 2 has the random value 0
Rank 4 has the random value 0
Rank 3 has the random value 1
Rank 5 has the random value 1
Rank 6 has the random value 0

Спасибо

1 Ответ

0 голосов
/ 03 октября 2018

Основная проблема: time(NULL)+world_rank.

Хорошо ли они объединены?


Все четные процессы, конечно, имеют младший значащий бит world_rank в виде 0 и нечетногоединицы 1, по определению.

Для заданного времени суток в секундах значение из time() может быть одинаковым для каждого запуска процесса, если оно началось примерно в одно и то же время.

Мы можем быть достаточно уверены в свойствах time(): оно увеличивается, оно одинаково каждую секунду.

Мы не знаем, что идентификатор процесса не зависит от time .


Первым шагом было бы сообщить time и ID процесса .

time_t t = time(NULL);
printf("time() %lld\n", (long long) t);
printf("process %d\n", world_rank);

Nextобъедините time и ID процесса в некотором смысле лучше, чем +.Давайте хешируем world_rank или t, чтобы гарантировать, что значения не являются тривиально не связанными.

Пример: тривиальный Линейный конгруэнтный генератор

const unsigned m = 1664525u;
const unsigned c = 1013904223u;
unsigned t_hashed = (unsigned) t;
t_hashed = m*t_hashed + c;

Теперь объединяем:

srand(t_hashed ^ world_rank);

Если это не дает удовлетворительных результатов, необходимы другие источники числовой энтропии .

...