2012-01-19 4 views
2

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

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

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

[EDIT 1]: проверены политики управления и статического планирования.

[EDIT 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); 
     } 
    } 

Где КОМП выполняет какое-то линейное применение значений в A, B, C в положении к + J * N + I * NN (и некоторые из их соседей). Дело в том, что этот код в GCC и ICC вызвал проблему, которую я описал. Дело в том, что я обнаружил, что я меняю инициализацию a, b, c, d на какое-то значение, отличное от 0.0f (f.ex, 0.5f), что вещь, затрачиваемая на увеличение временного шага, не возникает.

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

+0

Попробуйте включить/включить переменные GCC и libgomp/enviroment: 'GOMP_CPU_AFFINITY = 0-31', где 31 - число ядер процессора -1; и 'OMP_WAIT_POLICY = active', чтобы получить более предсказуемые результаты. – osgx

+0

Спасибо!Но я пробовал то, что твоя цель и поведение сохраняется. Может ли быть, что OpenMP пытается различить chunsizes, пока не найдет оптимальное распределение рабочей нагрузки? Я не задавал каких-либо конкретных фрагментов. –

+0

Можете ли вы показать код модели, который по-прежнему имеет такое же поведение? – osgx

ответ

1

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

Работа с денормалами может изменяться в зависимости от времени выполнения по сравнению с режимом «Сброс до нуля» (когда все денормалы округляются до нуля). В компиляторе будет больше работы, которая корректно вычисляет денормалы. И количество операций может варьироваться между итерациями.

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

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

В НКУ денормализованные числа-это-ноль включен только -ffast-math вариант, который не установлен какой-либо из -O1 , -O2, -O3: (grep a -ffast-math). -ffast-math включает в себя денормалы, игнорирующие (bug36821,comment#1)

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

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

+0

Спасибо, но это не было решением. Фактически, это увеличивало время вычисления, но не решая проблему. –

+0

Какие операции используются в COMP? Что такое процессор? Есть ли «turbo boost» или некоторые энергосберегающие процессоры? Используется ли AVX? – osgx

+0

COMP только делает линейные операции: умножения и дополнения, все в первом порядке. Что касается динамической частоты. в процессоре (думаю, вы это имели в виду), я не уверен, я должен взглянуть на это. И в том, что касается AVX, я не представил никакой векторизации, только то, что делает компилятор в O3, то есть с использованием регистров и инструкций XXMS, но только по скалярному пути (я проверил код ассемблера, чтобы проверить это) , –

Смежные вопросы