ПАРАЛЛЕЛЬНЫЕ АЛГОРИТМЫ УМНОЖЕНИЯ МАТРИЦ И ВЕКТОРОВ УМНОЖЕНИЕ МАТРИЦЫ НА ВЕКТОР Ab c n ci Aijb j j 1 РЕАЛИЗАЦИЯ ДЛЯ СИСТЕМ С ОБЩЕЙ ПАМЯТЬЮ Обрабатывать различные строки на разных вычислительных ядрах. Пример реализации на OpenMP void mxv(int n, double* a, double* b, double* c) { int i; #pragma omp parallel for for(i = 0; i < n; i ++){ double s = 0.; int j; double *v; v = a + i * n; for(j = 0; j < n; j ++) { s += v[j] * b[j]; } c[i] = s; } } УМНОЖЕНИЕ МАТРИЦ: БАЗОВЫЙ АЛГОРИТМ void mxm (int n, double* a, double* b, double* c) { for(i := 0; i < n; i ++) { for(j: =0; j < n; j ++) { c[i*n + j] = 0.; for(k : = 0; k < n; k ++) c[i*n + j] += a[i*n + k] * b[k*n + j]; } } } Недостаток: доступ по столбцу к элементам матрицы b во внутреннем цикле. УМНОЖЕНИЕ МАТРИЦ: БОЛЕЕ ЭФФЕКТИВНЫЙ АЛГОРИТМ void mxm2(int n, double* a, double* b, double* c) { int i; for(i = 0; i < n; i ++){ int k; for(k = 0; k < n; k ++) { int j; for(j = 0; j < n; j ++) { if(k == 0) c[i * n + j] = 0.; c[i * n + j] += a[i * n + k] * b[k * n + j]; } } } } УМНОЖЕНИЕ МАТРИЦ: РЕАЛИЗАЦИЯ НА OpenMP void mxm2(int n, double* a, double* b, double* c) { int i; #pragma parallel for for(i = 0; i < n; i ++){ int k; for(k = 0; k < n; k ++) { int j; for(j = 0; j < n; j ++) { if(k == 0) c[i * n + j] = 0.; c[i * n + j] += a[i * n + k] * b[k * n + j]; } } } } РЕЗУЛЬТАТЫ ВЫЧИСЛИТЕЛЬНОГО ЭКСПЕРИМЕНТА С оптимизацией (-О) Без компилятороной оптимизации Рассматривается матрица 1024x1024, процессор 4 core Xeon, 3 GHz Число потоков Базовый алгоритм Улучшенный алгоритм 1 42.9 13.4 2 23.4 6.8 4 12.8 3.4 8 6.4 1.7 Число потоков Базовый алгоритм Улучшенный алгоритм 1 57.5 4.0 2 31.3 2.0 4 20.0 1.3 8 10.9 0.7