2013-06-17 4 views
0

Я пытаюсь распараллелить for-loop с помощью OpenMP. Обычно это должно быть достаточно простым. Однако мне нужно выполнить инициализацию, зависящую от потока, до выполнения цикла for.OpenMP 'parallel for' с предшествующей инициализацией

В частности, у меня есть следующая проблема: у меня есть генератор случайных чисел, который не является потокобезопасным, поэтому мне нужно создать экземпляр RNG для каждого потока. Но я хочу убедиться, что не каждый поток будет генерировать одинаковые случайные числа.

Так что я попытался следующие:

#pragma omp parallel 
    { 
     int rndseed = 42; 
     #ifdef _OPENMP 
      rndseed += omp_get_thread_num(); 
     #endif 

     // initialize randon number generator 

     #pragma omp for 
     for (int sampleid = 0; sampleid < numsamples; ++sampleid) 
     { 
      // do stuff 
     } 
    } 

Если я использую эту конструкцию, я получаю следующее сообщение об ошибке во время выполнения:

Фатальная ошибка Пользователь 1002: «#pragma OMP для» неправильно вложенными в конструкции совместного использования

Итак, есть ли способ инициализации, зависящий от потока?

спасибо

+0

Почему бы не высеять каждый RNG из '/ dev/urandom', который даст вам хорошие семена и разные значения каждой нити? –

+1

Я не знаю, почему это не для вас, но для использования случайных чисел см. Это http://stackoverflow.com/questions/10624755/openmp-program-is-slower-than-sequential-one –

+1

Код, который вы показываете не является причиной проблемы. (Вы не показываете конструкцию совместного использования, вложенную в конструкцию совместного использования). Я ожидаю, что у вас на самом деле есть * другой * #pragma omp для где-то внутри «do stuff». –

ответ

0

Ошибки у вас есть:

Fatal User Error 1002: '#pragma omp for' improperly nested in a work-sharing construct 

относится к незаконной вложенности распараллеливания конструирует. В самом деле, стандарт OpenMP 3.1 дает следующие ограничения в разделе 2.5:

  • Каждого распараллеливание регион должен быть встречаются все потоки в команде или никто вообще.
  • Последовательность областей регистрации и встречающихся областей барьеров должна быть одинаковой для каждого потока в команде.

Из строк, приведенных выше, следует, что гнездовые различные распараллеливание конструкции внутри одной и той же параллельной области он не соответствует.

Несмотря на то, что нелегальная вложенность не отображается в вашем фрагменте, я предполагаю, что он был скрыт за упрощением сообщения относительно фактического кода.Просто чтобы дать вам намек наиболее распространенные случаи:

  • петля распараллеливание конструкции гнездились внутри одной конструкции (аналогично на примере here)
  • петля распараллеливание конструкции вложен внутри другой конструкции петли

В случае, если вас интересует, в this answer последний случай обсуждается m руды в деталях.

0

Я думаю, что ошибка дизайна.

Параллельный цикл - это не только N потоков с N числом ядер, но, возможно, N * X потоков, с 1 < = N * X < numsamples.

Если вы хотите «итерационную приватную» переменную, тогда объявите ее только внутри тела цикла (но вы уже это знаете); но объявление переменной, зависящей от потока, для использования внутри параллельного цикла, вероятно, недостаточно оправдано.