Многомерный вложенный цикл OpenMP - PullRequest
10 голосов
/ 13 марта 2011

Как правильно распараллеливать многомерный смущающий параллельный цикл в OpenMP? Количество измерений известно во время компиляции, но какие измерения будут большими, нет. Любой из них может быть один, два или миллион. Конечно, я не хочу N omp parallel для N-мерного цикла ...

Мысль:

  • Проблема концептуально проста. Только самый внешний «большой» цикл должен быть распараллелен, но размеры цикла неизвестны во время компиляции и могут измениться.

  • Будет ли динамическая установка omp_set_num_threads(1) и #pragma omp for schedule(static, huge_number) сделать определенные параллелизации циклов запретом? Будет ли это иметь нежелательные побочные эффекты / накладные расходы? Чувствуется как клудж

  • Спецификация OpenMP (2.10, A.38, A.39) говорит о разнице между согласующимся и несоответствующим вложенным параллелизмом, но не предлагает лучший подход к этой проблеме.

  • Переупорядочение циклов возможно, но может привести к большому количеству ошибок кэша Развертывание возможно, но нетривиально. Есть ли другой способ?

Вот что я хотел бы распараллелить:

for(i0=0; i0<n[0]; i0++) {
  for(i1=0; i1<n[1]; i1++) {
    ...
       for(iN=0; iN<n[N]; iN++) {
         <embarrasingly parallel operations>
       }
    ...
  }
}

Спасибо!

1 Ответ

9 голосов
/ 13 марта 2011

Директива collapse - это, вероятно, то, что вы ищете, как описано здесь .По существу, это будет формировать единый цикл, который затем будет парализован и предназначен именно для таких ситуаций.Так что вы должны сделать:

#pragma omp parallel for collapse(N)
for(int i0=0; i0<n[0]; i0++) {
  for(int i1=0; i1<n[1]; i1++) {
    ...
       for(int iN=0; iN<n[N]; iN++) {
         <embarrasingly parallel operations>
       }
    ...
  }
}

и все будет готово.

...