Неожиданные результаты с OpenMP на i7 и Xeon - PullRequest
3 голосов
/ 03 ноября 2010

распараллеливая два вложенных цикла for, я столкнулся с поведением, которое не могу объяснить.Я пробовал три разных типа распараллеливания с использованием OpenMP на i7 860 и xeon E5540, и я ожидал, что код ведет себя более или менее одинаково на обеих платформах, что означает, что одна из платформ должна быть быстрее для всех трех разных случаевЯ проверял.Но это не так:

  • Для случая 1 Xeon быстрее на ~ 10%,
  • для случая 2, i7 быстрее в 2 раза и
  • для случая 3, Xeon снова быстрее с коэффициентом 1,5

У вас есть идея, что может вызвать это?

Пожалуйста, укажите, когда вам нужно больше информации или разъяснений!

Для уточнения, мой вопрос имеет более общий характер.Если я запускаю один и тот же код на i7 и в системе xeon, разве использование OpenMP не должно привести к сопоставимым (пропорциональным) результатам?

псевдокод:

for 1:4
    for 1:1000
        vector_multiplication
    end
end

Случаи:

case 1: нет pramga omp нет параллелизации

case 2: pragma omp для первого цикла for

case 3: pragma omp для второго цикла for

Results

Вот фактические числа из команды time:

case 1

Time   Xeon        i7
real   11m14.120s  12m53.679s
user   11m14.030s  12m46.220s
sys      0m0.080s    0m0.176s

case 2

Time   Xeon        i7
real    8m57.144s   4m37.859s
user   71m10.530s  29m07.797s
sys      0m0.300s   0m00.128s

case 3

Time   Xeon        i7
real    2m00.234s   3m35.866s
user   11m52.870s  22m10.799s
sys     0m00.170s   0m00.136s

[Update]

Спасибо за все подсказки.Я все еще исследую причину.

Ответы [ 3 ]

2 голосов
/ 04 ноября 2010

Здесь были хорошие ответы о возможных вариациях с эффектами компиляции и т. Д., Которые вполне верны; но есть и другие причины ожидать различий. Подобные довольно простые (например, с низкой арифметической интенсивностью) вычисления, как правило, очень чувствительны к пропускной способности памяти; и объем доступной пропускной способности памяти для потока будет зависеть от того, сколько потоков вы запустили. Память настроена одинаково в обеих системах?

Похоже, у i7 860 более высокая тактовая частота, но у E5540 общая пропускная способность памяти выше. Поскольку в случае 2 можно использовать только 4 потока, а в случае 3 можно использовать больше, совсем не сумасшедшим думать, что в случае с 4 потоками тактовая частота выигрывает, а в случае с 8 потоками - повышенная конкуренция памяти ( 8 потоков, пытающихся вытянуть / вытолкнуть значения), подает руку к более высокому диапазону с Xeon.

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

Если вы хотите попытаться определить, играет ли здесь роль ограниченная пропускная способность памяти, вы можете искусственно добавить дополнительные вычисления к задаче (например, умножить exp (sin (a)) на cos (b) * cos (b) или что-то еще), чтобы гарантировать, что проблема связана с вычислениями, исключая одну переменную, когда вы пытаетесь разобраться в сути дела. Компиляция кода в каждой системе с оптимизацией для этой конкретной машины (с -march или -xHost или что у вас) исключает другую переменную. Если гиперпоточность включена, ее отключение (или просто установка OMP_NUM_THREADS на количество физических ядер) избавляет от другой переменной. Как только вы поймете, что происходит в этом упрощенном случае, ослабление ограничений выше одного за другим должно помочь вам понять, что происходит немного лучше.

0 голосов
/ 03 ноября 2010

Это скорее комментарий, чем ответ.

Не совсем понятно, что вы измерили.Для большей уверенности я бы хотел:

  1. Вставить временные операторы в точках моего кода, чтобы сообщить о времени выполнения.Таким образом, я знаю, что я измеряю, с большей уверенностью, чем дает мне команда времени Linux.

  2. Используйте 2 разных компилятора, чтобы убедиться, что я что-то измеряю в OpenMP, а не в аспектаходна реализация этого.

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

0 голосов
/ 03 ноября 2010

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

#pragma omp parallel for
for (size_t i = start, is = stop; i < is; ++i) ...

, чтобы убедиться, что выражения start и stop вычисляются в начале.(или используйте _Pragma, см. мой другой ответ.)

Тогда единственный способ убедиться, что это действительно успешно, - это посмотреть код ассемблера (обычно опция -S).

Если это не смотреть на другие параметры компилятора.У gcc есть опция -march=native, которая оптимально компилируется для реальной архитектуры.Другие платформы могут иметь аналогичные параметры.Начните с поиска лучших вариантов архитектуры для варианта 1.

...