Подтвердить что ты не робот

Безопасность потока std:: random_device

У меня есть код, который выглядит примерно так:

std::random_device rd;

#pragma omp parallel
{
    std::mt19937 gen(rd());
    #pragma omp for
    for(int i=0; i < N; i++)
    {
        /* Do stuff with random numbers from gen() */
    }
}

У меня есть несколько вопросов:

  • Является ли std::random_device потокобезопасным? т.е. собирается ли что-то сделать бесполезным, когда сразу несколько потоков называют его?
  • Это вообще хорошая идея? Должен ли я беспокоиться о перекрывающихся потоках случайных чисел?
  • Есть ли лучший способ достичь того, что я хочу (независимые случайные числовые потоки в каждом потоке - я не слишком беспокоюсь о воспроизводимости на данный момент)?

В случае, если это имеет какое-то значение для работы std::random_device, я в основном работает в Windows, хотя я бы хотел, чтобы код работал одинаково хорошо в Linux и OSX.

4b9b3361

Ответ 1

ПРИМЕЧАНИЕ.. Этот ответ работает на GCC Linux, но OpenMP вообще не гарантируется взаимодействие с моделью потоков std, поэтому функции, такие как thread_local, могут не работать.

(удалит этот ответ, если это позволит мне)

Я бы, вероятно, создал локальную статику PRNG и инициализировал ее временным std::random_device:

#pragma omp parallel
{
    // different gen for each thread
    thread_local static std::mt19937 gen(std::random_device{}());
    #pragma omp for
    for(int i=0; i < N; i++)
    {
        /* Do stuff with random numbers from gen() */
    }
}

Это даст вам ровно один std::mt19937 за поток и сэкономит время на их построение с помощью нескольких вызовов функции.