В последние месяцы я работал с умножением компьютерных матриц и провел несколько тестов с использованием openMP и eigen3.
Испытания проводились на следующих машинах:
Компьютер 1:
Процессор Intel Core i7-3610QM @ 2,30 ГГц / 6 ГБ ddr3
Компьютер 2:
Шестиядерный процессор AMD Opteron ™ 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
Eigen3 _____________ 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 complete превосходит версию OpenMP плюс все тесты, проведенные на компьютере 1.
Любая идея, почему я получаю эти результаты и почему eigen3 не так быстро в компьютере 1, как в компьютере 2?
Спасибо за ваши ответы.
Огромная разница между последовательной и параллельной версиями обусловлена тем, что используются разные алгоритмы. Последовательная версия использует обычный наивный O (N ^ 3) без каких-либо оптимизаций, в то время как параллельные версии являются оптимизированными версиями — с использованием блоков. Используя тот же алгоритм, время последовательной версии составляет около 10 (компьютер 1) и 50 (для компьютера 2) — извините, я должен был поместить эти значения в первый пост.
Разница между производительностью Eigen3 и производительностью OpenMP на первом и втором компьютерах, по-видимому, связана с количеством запущенных потоков и количеством доступных физических процессоров. Мы обнаружили, что производительность Eigen3 ухудшается, если количество запущенных потоков больше доступного количества физических процессоров, а это не относится к OpenMP
В тестах количество запущенных потоков в обоих случаях было равно общему количеству процессоров (виртуальных + физических).
На компьютере 1 производительность Eigen3 хуже, поскольку общее количество процессоров (виртуальных + физических — из-за гиперпоточности) больше, чем количество физических процессоров.
В компьютере 2 производительность Eigen3 лучше, потому что общее количество процессоров такое же, как и количество физических процессоров. Если мы используем удвоенное количество физических процессоров для числа потоков, производительность Eigen3 также ухудшается, а openMP фактически немного улучшается.
Других решений пока нет …