Производительность умножения матрицы Eigen3 зависит от процессора?

В последние месяцы я работал с компьютерными матричными умножениями и провел несколько тестов с использованием openMP и eigen3.

Испытания проводились на следующих машинах:

Компьютер 1:

ЦП Intel Core i7-3610QM с тактовой частотой 2,30 ГГц / 6 ГБ ddr3

Компьютер 2:

Шестиядерный процессор AMD Opteron(tm) 2435 2,60 ГГц (2 процессора) / 16 ГБ

Для openMP использовался следующий алгоритм умножения матрицы на матрицу:

void matrix4openmp(void)
{
    int j;

#pragma omp parallel for 
for (j=0;j<N; j+=2){
  double v1[N],v2[N];
    int i,k;
  for (i=0;i<N; i++){
     v1[i]=b[i][j];
     v2[i]=b[i][j+1];
  }

  for (i=0; i<N;i+=2){
     register double s00,s01,s10,s11;
     s00=s01=s10=s11=0.0;
     for (k=0;k<N;k++){
        s00 += a[i]  [k] * v1[k];
        s01 += a[i]  [k] * v2[k];
        s10 += a[i+1][k] * v1[k];
        s11 += a[i+1][k] * v2[k];
     }
     c[i]  [j]   =s00;
     c[i]  [j+1] =s01;
     c[i+1][j]   =s10;
     c[i+1][j+1]   =s11;
  }
}

Результаты были следующими:

_________________________Компьютер 1__________Компьютер 2

Последовательный________232,75600___________536,21400

OpenMP____________2,75764____________7,62024

Собственный 3_____________3,35090____________1,92970

*Время указано в секундах.

*Размеры матрицы были 2700 х 2500 и 2500 х 2700.

*Последовательные алгоритмы отличаются от OMP, это самая простая версия m-m умножения, которую можно увидеть здесь: http://pastebin.com/Pc9AKAE8.

* Инструкции SSE2 были активированы для тестов eigen3.

* OpenMP использует ядра по умолчанию, это все ядра, обнаруженные Windows, включая виртуальные.

Как видите, версия OpenMP работает быстрее на первом компьютере (i7), чем версия eigen3. Однако для компьютера 2 (2x Opteron) производительность eigen3 полностью превосходит версию OpenMP плюс все тесты, проведенные на компьютере 1.

Есть идеи, почему я получаю такие результаты и почему eigen3 не так быстр на компьютере 1, как на компьютере 2?


person RandomGuy    schedule 10.12.2012    source источник
comment
Можете ли вы заставить все реализации использовать SSE2? Opteron имеет больше и более быстрые ядра для прокачки необработанных тактовых частот памяти, что делает этот тест явно неравномерным. Я бы рекомендовал хотя бы уравнять набор инструкций (путем компиляции) и количество используемых ядер. (taskset).   -  person Steve-o    schedule 10.12.2012
comment
@High Performance Mark Я забыл добавить, что в последовательной версии не используется тот же алгоритм, который я опубликовал, он использует самую простую версию, которая не использует никаких оптимизаций. Вот этот: pastebin.com/Pc9AKAE8 Вот почему он, вероятно, намного медленнее, поскольку должен использовать только оперативную память вместо кэши и регистры.   -  person RandomGuy    schedule 10.12.2012
comment
@Steve-o, я попробую с включенным SSE в последовательном режиме и OpenMP и сообщу вам об этом. Количество используемых ядер — это значение по умолчанию для openMP, это все виртуальные процессоры, которые Windows обнаруживает на каждой машине (8 на компьютере_1 и 12 на компьютере_2). Когда вы имеете в виду подкачку необработанных часов памяти, вы имеете в виду передачу данных ram-cpu?   -  person RandomGuy    schedule 10.12.2012
comment
@Steve-o Где интересные тесты с одинаковым количеством потоков для процессора (4 потока) и включенным SSE2 для всех тестов: pastebin.com/mkWCicb7 Теперь это кажется более понятным. Кажется, что i7 работает намного медленнее с 8 потоками, чем с 4, поскольку у него всего 4 физически процессора. Я, вероятно, еще раз протестирую количество потоков, установленных на количество физических процессоров, а не на виртуальные.   -  person RandomGuy    schedule 11.12.2012
comment
Вы должны иметь в виду следующее: 1. Eigen3 имеет встроенное распараллеливание матрично-матричных продуктов с использованием OpenMP (если вы компилируете его с -fopenmp) 2. Eigen должен быть скомпилирован с включенными оптимизациями компилятора (-O2 или -O3 ) и утверждения отключены (-DNDEBUG).   -  person Robert Rüger    schedule 15.01.2013
comment
Спасибо, я выполнил все эти шаги и пришел к заключению своего последнего сообщения. Я написал технический отчет, который я приведу в качестве ответа на этот вопрос, как только у меня будет свободное время.   -  person RandomGuy    schedule 15.01.2013


Ответы (1)


Спасибо за ваши ответы.

Огромная разница между последовательной и параллельной версиями связана с использованием разных алгоритмов. Последовательная версия использует обычный наивный O(N^3) без каких-либо оптимизаций, в то время как параллельные версии являются оптимизированными версиями с использованием блоков. Используя тот же алгоритм, время последовательной версии составляет около 10 (компьютер 1) и 50 (для компьютера 2) — извините, нужно было поместить эти значения в первый пост.

Разница между производительностью Eigen3 и производительностью OpenMP на первом и втором компьютерах, по-видимому, связана с количеством запущенных потоков и количеством доступных физических процессоров. Мы обнаружили, что производительность Eigen3 ухудшается, если количество запущенных потоков превышает доступное количество физических процессоров, но это не относится к OpenMP.

В тестах количество запущенных потоков для обоих случаев было равно общему количеству процессоров (виртуальных + физических).

На компьютере 1 производительность Eigen3 хуже, потому что общее количество процессоров (виртуальные + физические - из-за гиперпоточности) больше, чем количество физических процессоров.

На компьютере 2 производительность Eigen3 лучше, потому что общее количество процессоров совпадает с количеством физических процессоров. Если мы используем двойное количество физических процессоров для количества потоков, производительность Eigen3 также ухудшается, а openMP фактически немного улучшается.

person RandomGuy    schedule 24.01.2013