使用循环平铺和OpenMP进行优化

时间:2019-05-30 04:27:59

标签: c optimization openmp

下面是我正在尝试使用OpenMP和循环切片(又称为循环阻止)进行优化的函数。但是,在我像下面那样应用循环平铺之后,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 个答案:

答案 0 :(得分:1)

首先,const long BLOCK_SIZE = 8*DIM;对我来说似乎非常可疑... 也许将*替换为/会更符合您的需求?

但是,即使如此,您仍然必须通过检查ijk索引没有超过其限制来处理这些限制。我让您找出实现该目标的方法。

算法的最后一点:您确定循环必须从索引1开始吗?

最后,关于OpenMP正确性的几点说明:

  • 尽管我没有发现任何错误,但是声明firstprivate(we_need, gimmie, dim,old,BLOCK_SIZE)并没有多大意义。这些可以愉快地停留在shared
  • 我真的不知道num_threads(omp_get_num_procs())是否正确。我的感觉是,它确实是有效的,但仅出于“安全性”考虑,我倾向于将对函数的调用与指令分开(通过先调用函数并将其结果存储在常量中,然后在指令中使用它) ,或在omp_set_num_threads()指令之前调用parallel
  • 算法固定后,您可能需要考虑添加一些collapse指令以提高在此处实现的并行度...

祝您代码顺利。

相关问题