ICC, GCC и OpenMP - PullRequest
       48

ICC, GCC и OpenMP

2 голосов
/ 19 января 2012

Я запускаю заданную проблему, которая распараллеливается с помощью OpenMP.Он выполняет заданное количество итераций одного и того же фрагмента кода, который обрабатывает объем данных.Находится на том уровне, где применяется OpenMP, превращая каждый поток в подобъем.Каждая итерация должна иметь одинаковую рабочую нагрузку, а также каждый подобъем.

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

Кто-нибудь наблюдал такое поведение в OpenMP в этих компиляторах?

[РЕДАКТИРОВАТЬ 1]: проверены политики управляемого и статического планирования.

[РЕДАКТИРОВАНИЕ 2]: кодвыглядит примерно так:

 #pragma omp parallel for schedule(static) private(i,j,k)
 for(i = 0; i < N; i++)
    for(j = 0; j < N; j++)
       for(k = 0; k < N; k++){
            a[ k+j*N+i*NN] =  0.f;
            b[ k+j*N+i*NN] =  0.f;
            c[ k+j*N+i*NN] =  0.f;
            d[ k+j*N+i*NN] =  0.f;
  }
 for( t = 0; t  < T; t+=dt){
   /* ... change some discrete values in a,b,c .... */
   /*       and propagate changes                   */    
  #pragma omp parallel for schedule(static) private(i,j,k)
    for(i = 0; i < N; i++)
       for(j = 0; j < N; j++)
          for(k = 0; k < N; k++){
            d[ k+j*N+i*NN ] = COMP( a,b,c,k+j*N+i*NN );
      }
  }

Где COMP выполняет какое-то линейное применение значений в a, b, c в позиции k + j * N + i * NN (и некоторых их соседей).Дело в том, что этот код в GCC и ICC вызвал проблему, которую я описал.Дело в том, что я обнаружил, что я изменяю инициализацию a, b, c, d на какое-то значение, отличное от 0.0f (f.ex, 0.5f), то есть не происходит увеличение времени, затрачиваемого на шаг по времени.

[РЕДАКТИРОВАТЬ 3]: Кажется, это не вина GOMP.То же самое происходит с отключенным OpenMP.Еще раз, с ICC (без или с openmp) не происходит вообще.Можно ли как-нибудь закрыть эту тему?

1 Ответ

1 голос
/ 24 января 2012

Может быть, COMP выполняет некоторые ненормальные операции, которые выполняются программно, а не аппаратно.

Работа с ненормированными числами может варьировать время выполнения по сравнению с режимом Flush-to-zero (когда каждая денормалическая часть округляется до нуля). Будет больше работы в компиляторе, который справедливо вычисляет денормалы. И объем работы может варьироваться между итерациями.

Компилятор Intel по умолчанию отключает ненормированные операции и устанавливает сбрасывание в ноль и денормализацию в ноль на любом уровне -O (-O0, -O1, -O2 и т. Д.).

Чтобы включить денормали, используйте: -no-ftz опция компилятора Intel (docs1) (docs2) или может быть -fp-model precise

В GCC denormals-are-zero поворачивается только с помощью опции -ffast-math, которая не устанавливается ни одним из -O1, -O2, -O3: (grep a -ffast-math) . -ffast-math включает в себя денормали, игнорирующие (bug36821, комментарий # 1)

Таким образом, если у вас много ненормальных значений в COMP, ICC проигнорирует их как ноль, а GCC выполнит большую обработку программного обеспечения.

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

...