Страницы

Поиск по вопросам

воскресенье, 8 декабря 2019 г.

LU разложение OpenMP

#openmp #c #алгоритм #cpp #распараллеливание


Почему параллельная версия работает за то же время или больше чем последовательная
версия алгоритма? Что я сделал не так?
LU разложение с помощью OpenMP:
void lup_od_omp(double* a, int n){

int i,j,k;

for(k = 0; k < n - 1; ++k)
{
    #pragma omp parallel for shared(a,n,k) private(i,j)
    for(i = k + 1; i < n; i++)
    {
        a[i*n + k] /= a[k*n + k];
        for(j = k + 1; j < n; j++)
        {
            a[i*n + j] -= a[i*n + k]*a[k*n + j];
        }
    }
}
}

P.S. Матрица хранится в одномерном массиве. Та же самая ситуация с временем выполнения
(параллельно >= последовательно) и с матрицей, хранящейся в двумерном массиве.    


Ответы

Ответ 1



Вопрос старый, но без ответа. Как вариант - проблема в том, что массив a совместно используется для записи в потоках. В таком случае параллельный вариант вполне может работать даже медленнее последовательного. На большем количестве ядер, думаю, эффект должен быть очевиднее. Каждая запись на ядре 0 будет вытеснять любое чтение на ядре 1 и наоборот - запись на ядре 1 будет вытеснять чтение по этим же адресам на ядре 0 (см. "когерентность кэша"). Решить проблему можно, если выделить каждому потоку свой буфер для сохранения результатов (равноудаленный друг от друга как минимум на 32/64 байта, а еще лучше - выровненный при этом на те же 32/64 байта [кэш-линия]). Замечание от @Михаил М, думаю, тоже в силе, но в таком случае, я уже сомневаюсь насчет корректности параллельного алгоритма: очевидно, в смежной ячейке может находиться значение, модифицированное другим потоком, а это поменяет результат вычислений.

Комментариев нет:

Отправить комментарий