Случайное число для каждого процесса в MPI

Я использую MPICH2 для реализации сортировки «нечетный-четный».
Я сделал реализацию, но когда я рандомизирую каждому процессу его значение,
одно и то же число рандомизировано для всех процессов.

Вот код для каждого процесса, каждый процесс рандомизировал его значение.

int main(int argc,char *argv[])
{
int  nameLen, numProcs, myID;
char processorName[MPI_MAX_PROCESSOR_NAME];
int myValue;

MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&myID);
MPI_Comm_size(MPI_COMM_WORLD,&numProcs);
MPI_Get_processor_name(processorName,&nameLen);
MPI_Status status;

srand((unsigned)time(NULL));
myValue = rand()%30+1;

cout << "myID: " << myID << " value: " << myValue<<endl;
MPI_Finalize();

return 0;
}

почему каждый процесс получает одинаковое значение?

Редактировать: спасибо за ответы 🙂

Я изменил линию

 srand((unsigned)time(NULL));

в

 srand((unsigned)time(NULL)+myID*numProcs + nameLen);

и это дает разные значения для каждого процесса 🙂

5

Решение

Эта задача не тривиальна.

Вы получаете те же номера, потому что вы инициализируете srand() с time(0), Какие time(0) делает возврат текущей секунды (начиная с эпохи). Так что, если все процессы имеют синхронизированные часы, все будут инициализироваться с тем же начальным числом, пока они вызывают srand() в ту же секунду, что вполне вероятно. Я наблюдал это даже на больших машинах.

Решение 1. Используйте локальные значения для инициализации случайного начального числа.

Что я сделал, так это включил в вычисление случайного семени некоторое использование памяти от cat /proc/meminfo в сочетании с /dev/random, которые являются более локальными для физической машины, чем часы. Обратите внимание, что это все еще может не сработать для N задач на 1 машине. Но если я правильно помню, я также использовал task_id, Все, что является локальным для задачи, будет достаточно. Объединение вещей тоже хорошая идея. После всего этого вычисления должны быть очень короткими по сравнению с реальными вычислениями. И лучше оставаться на безопасной стороне.

Решение 2. Подсчитайте семена как этап предварительной обработки.

Вы также можете генерировать случайные семена из task 0 используя ваш метод и распространять его с send-to-all, Тем не менее, это может иметь проблемы с масштабированием при масштабировании (например, 10 ^ 5 процессов). Вы также можете использовать любой другой метод для загрузки параметров и просто подготовить семена в качестве шага предварительной обработки. Однако это также включает в себя некоторую нетривиальную работу.

6

Другие решения

Это потому, что ваше семя недостаточно меняется, и случайность зависит от вашего семени.

От srand документы:

Для каждого другого начального значения, используемого в вызове srand,
Можно ожидать, что генератор псевдослучайных чисел будет генерировать другое
последовательность результатов в последующих вызовах rand.

РЕДАКТИРОВАТЬ: попробуйте сгенерировать семена заранее или поменяйте семена вручную для каждого srand вызов.

2

По вопросам рекламы [email protected]