下面是我正在尝试使用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);
}
答案 0 :(得分:1)
首先,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
指令以提高在此处实现的并行度... 祝您代码顺利。