@denjamin11

Как распараллелить тройной цикл for с помощью OpenMP?

Здравствуйте, нужна помощь с распараллеливанием.

void kernel_heat_3d (int tsteps, int n, double A[ n][n][n], double B[ n][n][n])
{
    int t, i, j, k;

    for (t = 1; t <= TSTEPS; t++) {
        for (i = 1; i < n-1; i++) {
            for (j = 1; j < n-1; j++) {
                for (k = 1; k < n-1; k++) {
                    B[i][j][k] = 0.125 * (A[i+1][j][k] - 2.0 * A[i][j][k] + A[i-1][j][k])
                                 + 0.125 * (A[i][j+1][k] - 2.0 * A[i][j][k] + A[i][j-1][k])
                                 + 0.125 * (A[i][j][k+1] - 2.0 * A[i][j][k] + A[i][j][k-1])
                                 + A[i][j][k];
                }
            }
        }
        for (i = 1; i < n-1; i++) {
           for (j = 1; j < n-1; j++) {
               for (k = 1; k < n-1; k++) {
                   A[i][j][k] = 0.125 * (B[i+1][j][k] - 2.0 * B[i][j][k] + B[i-1][j][k])
                                + 0.125 * (B[i][j+1][k] - 2.0 * B[i][j][k] + B[i][j-1][k])
                                + 0.125 * (B[i][j][k+1] - 2.0 * B[i][j][k] + B[i][j][k-1])
                                + B[i][j][k];
               }
           }
       }
    }

}
  • Вопрос задан
  • 179 просмотров
Пригласить эксперта
Ответы на вопрос 1
wataru
@wataru
Разработчик на С++, экс-олимпиадник.
В вашем примере скорее всего достаточно распаралеллить только циклы по i.

Но, если у вас n меньше количества потоков, то можно использовать диррективу collapse. Подробнее можете почитать в документации (на странице 185).

Или можете расплющить 3 вложенных цикла в один руками так:
int n3 = (n-2)*(n-2)*(n-2);
for (int iteration = 0; iteration < n3; ++iteration) {
  i = iteration / ((n-2)*(n-2)) + 1;
  j = iteration / (n-2) % (n-2) + 1;
  k = iteration % (n-2) + 1;
  // тут идет содержимое трех циклов по i,j,k = 1..n-2
}

Это просто перенумерация всех троек значений. Каждую тройку индексов i,j,k можно рассматривать как трехзначное число в (N-2)-ичной системе счисления. Поэтому можно каждое число от 0 до (n-2)^3 разложить в n-2)-ичную систему счисления через / и % и получить три индекса.

Но collapse и, тем более, ручной вариант будут иметь накладные расходы на вычисление индексов. Поэтому их имеет смысл использовать только если у вас n меньше количества доступных потоков.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы