Я намерен написать заявление на C++ 11 для Linux, который делает некоторые численное моделирование (не криптография) на основе примерно один миллион псевдослучайных чисел 32bit. Чтобы ускорить работу, я хотел бы выполнить симуляцию в параллельных потоках, используя все ядра настольного процессора. Я бы хотел использовать Mersenne Twister mt19937
, предоставляемый boost как PRNG, и я предполагаю, что по соображениям производительности у меня должен быть такой PRNG на поток. Теперь я не уверен, как их семени, чтобы не генерировать одну и ту же последовательность случайных чисел в нескольких потоках.Случайные числа для нескольких потоков
Альтернативы
Вот альтернативы, которые я думал до сих пор:
семени ГСЧ для каждого потока независимо от
/dev/urandom
.Меня немного беспокоит случай, когда пул энтропийных систем исчерпывается, так как я не знаю, как работает внутренний PRNG системы. Может случиться так, что я случайно получаю последовательные семена, которые точно определяют последовательные состояния Mersenne Twister, из-за того, что
/dev/urandom
использует сам Мерсенн Твистер? Наверное, сильно связан с моими опасениями в отношении следующего пункта.Семена один PRNG от
/dev/urandom
и другие от первого.В принципе такая же проблема: хорошо или плохо использовать один PRNG для посева другого, который использует тот же алгоритм? Или, другими словами, считывает ли 625 32-битных целых чисел из
mt19937
непосредственно во внутреннее состояние генератораmt19937
в любой момент в течение этого поколения?Семена сперва с информацией, не относящейся к Мерсенне.
Как использовать тот же алгоритм для генерации случайных чисел и генерации начального семени, как-то вроде бы плохой идеи, я подумал о введении некоторого элемента, который не зависит от алгоритма Мерсенна Твистера. Например, я мог бы XOR идентификатор потока в каждый элемент исходного вектора семени. Это улучшает ситуацию?
Поделитесь одним PRNG среди тем.
Это гарантирует, что существует только одна последовательность со всеми известными и желательными свойствами Mersenne Twister. Но накладные расходы на блокировку, необходимые для контроля доступа к этому генератору, меня несколько волнуют. Поскольку я не нашел никаких доказательств обратного, я предполагаю, что я, как пользователь библиотеки, несут ответственность за предотвращение одновременного доступа к PRNG.
Предсготовить все случайные числа.
У этого будет один поток, который генерирует все необходимые 1M случайные числа спереди, которые будут использоваться различными потоками позже. Требование к памяти 4M было бы небольшим по сравнению с объемом всего приложения. Меня больше всего беспокоит такой подход: генерация самих случайных чисел не является параллельной. Весь этот подход также не слишком хорошо масштабируется.
Вопросы
Какой из этих подходов вы могли бы предложить, и почему? Или у вас есть другое предложение?
Знаете ли вы, какие из моих проблем оправданы и которые просто из-за моего отсутствия понимания того, как все работает?
У меня был такой же вопрос раньше. http://stackoverflow.com/questions/14804808/seed-a-random-generator-without-time-in-java-cross-plateformably К счастью, я нахожусь на Java – YankeeWhiskey
@YankeeWhiskey, [принятый ответ там] (http://stackoverflow.com/a/14804828/1468366) выглядит как вариант 3 здесь: вы высеиваете их из UUID, которые генерируются из «SecureRandom», который, в свою очередь, использует зависящие от платформы энтропийные источники и не просто Mersenne Twister , – MvG
Все предлагаемые подходы приведут к получению повторяющихся случайных чисел. В общем, вы запрашиваете 2 * 20 «случайных» чисел из возможных 2 ** 32 из них. Это требует многого, поэтому вам нужно переосмыслить, какие свойства вы хотите от 1 миллиона случайных 32-битных целых чисел. Если уникальность является одной из них, то ни один из этих подходов не будет работать. –