Оптимизация с помощью Loop Tiling и OpenMP - PullRequest
0 голосов
/ 30 мая 2019

Ниже моя функция, которую я пытаюсь оптимизировать, используя OpenMP и Loop Tiling (или Loop Blocking). Однако мой вывод out в настоящее время дает неправильное значение после того, как я применил циклическое разбиение, как показано ниже. Может кто-нибудь просмотреть мой код и указать, что делает его неправильным. Большое вам спасибо

#include <stdlib.h>
#include <stdio.h>
#include <omp.h>
#include "utils.h"
const long BLOCK_SIZE = 8*DIM;
int i, j, k,ii,jj,kk, dim = DIM-1;

long compute, out = 1.0, we_need, gimmie;

void work_it_par(long *old, long *new)
{
 we_need = need_func();
 gimmie = gimmie_func();

 #pragma omp parallel for private(i,j,k,ii,jj,kk, compute)      firstprivate(we_need, gimmie, dim,old,BLOCK_SIZE) reduction(+:out)   num_threads(omp_get_num_procs())
for (ii=1; ii<dim-BLOCK_SIZE; ii+=BLOCK_SIZE) {
  for (jj=1; jj<dim-BLOCK_SIZE; jj+=BLOCK_SIZE) {
    for (kk=1; kk<dim-BLOCK_SIZE; kk+=BLOCK_SIZE) {
      for (i=ii; i<ii+BLOCK_SIZE; i++) {
        for (j=jj; j<jj+BLOCK_SIZE; j++) {
          for (k=kk; k<kk+BLOCK_SIZE; k++) {
            //int temp = i*DIM*DIM+j*DIM+k;
            compute = old[i*DIM*DIM+j*DIM+k] * we_need;
            out += compute / gimmie;
          }
        }
      }

    }
  }
}

printf("AGGR:%ld\n",out);

}

1 Ответ

1 голос
/ 30 мая 2019

Прежде всего, const long BLOCK_SIZE = 8*DIM; мне кажется очень подозрительным ... Может быть, замена * на / будет больше, чем вы хотели?

Но даже при том, что вам все равно приходится иметь дело с ограничениями, проверяя, чтобы индексы i, j и k не выходили за их пределы. Я дам вам понять, как этого добиться.

Последний пункт алгоритма: вы уверены, что ваши циклы должны начинаться с индекса 1?

Наконец, несколько замечаний по поводу правильности OpenMP:

  • хотя я не вижу в этом ничего плохого, объявление firstprivate(we_need, gimmie, dim,old,BLOCK_SIZE) не имеет особого смысла. Они могли бы счастливо остаться shared.
  • Я действительно не знаю, правильно ли num_threads(omp_get_num_procs()) или нет. Мне кажется, что это действительно допустимо, но просто для «безопасности» я бы хотел отделить вызов функции от директивы (либо сначала вызвав функцию и сохранив ее результат в константе, либо используя его в директиве или по телефону omp_set_num_threads() перед директивой parallel)
  • когда ваш алгоритм исправлен, вы можете подумать о добавлении директивы collapse, чтобы увеличить уровень параллелизма, которого вы здесь достигли ...

Удачи с вашим кодом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...