我将代码带到 GPU 上。这段代码有一个使用私有数组的内核。这意味着该数组是在内核循环中声明的。
当我将代码移植到 OpenACC 时,我得到了错误的结果。对我来说,看起来这个数组是在 GPU 向量线程之间共享的,这会导致几个竞争条件。
我用外部调用组织了以下示例,因为这就是我的原始代码的样子。
标头.h:
#define N 100000
#define K 16
#pragma acc routine
void assign_i_to_privj(int * priv, int j, int i);
#pragma acc routinetnumpy
void add_privi_to_sum(int * priv, int i, int *sum);
主.c:
#include "header.h"
int main(void){
int A[N];
#pragma acc data copy(A)
{
#pragma acc parallel loop
for(int i=0; i<N;i++){
int priv[K];
int sum=0;
int j=0;
while(1){
if(j>=K) break;
assign_i_to_privj(priv, j, i);
j++;
}
j=0;
while(1){
if(j>=K) break;
add_privi_to_sum(priv, j, &sum);
j++;
}
sum/=K; // now sum == i;
A[i]=sum;
}
}
//now A[i] == i
for(int i=0; i<123; i++) printf("A[%d]=%d ",i, A[i]);
printf("\n");
return 0;
}
fc:
#include "header.h"
void assign_i_to_privj(int *priv, int j, int i){
priv[j]=i;
}
void add_privi_to_sum(int *priv, int j, int *sum){
(*sum)+=priv[j];
}
我可以看到带有cc -v
返回的编译器版本Export PGI=/opt/pgi/17.5.0
。
编译:
cc -g -lnvToolsExt -O2 -acc -ta=tesla:cc60 -c11 -mp -Minfo -Mlarge_arrays -c main.c &&
cc -g -lnvToolsExt -O2 -acc -ta=tesla:cc60 -c11 -mp -Minfo -Mlarge_arrays -c f.c &&
cc -g -lnvToolsExt -O2 -acc -ta=tesla:cc60 -c11 -mp -Minfo -Mlarge_arrays f.o main.o -o acc.exe &&
srun -n 1 acc.exe
代码应将所有A[i]
元素设置为等于i
. 当我在 OpenACC 支持下运行此代码时,我得到完全错误的结果。我的猜测是比赛条件。没有openacc
编译的版本可以正常运行。在运行结束时A[i]==i
所以,我的问题是:如何使用 OpenACC使一个小数组对所有GPU 线程都是私有的?