我正在使用OpenACC进行动态数组分配。我的分配方式如下:
float **a;
float **b;
float **c;
float **seq;
a=(float**)malloc(SIZE*sizeof(float*));
b=(float**)malloc(SIZE*sizeof(float*));
c=(float**)malloc(SIZE*sizeof(float*));
seq=(float**)malloc(SIZE*sizeof(float*));
for(i=0; i<SIZE; i++){
a[i]=(float*)malloc(SIZE*sizeof(float));
b[i]=(float*)malloc(SIZE*sizeof(float));
c[i]=(float*)malloc(SIZE*sizeof(float));
seq[i]=(float*)malloc(SIZE*sizeof(float));
}
以下是我与矩阵add并行的方法:
#pragma acc kernels copyin(a[0:SIZE][0:SIZE],b[0:SIZE][0:SIZE]) copy(c[0:SIZE][0:SIZE])
for (i = 0; i < SIZE; ++i) {
for (j = 0; j < SIZE; ++j) {
c[i][j] = a[i][j] + b[i][j];
}
}
当我使用pgcc
编译此代码时,它会在循环迭代中检测对float**
指针的依赖性,并生成所有标量内核(每块1个块1个线程),其执行效果不佳:
40, Complex loop carried dependence of '*(*(b))' prevents parallelization
Complex loop carried dependence of '*(*(a))' prevents parallelization
Complex loop carried dependence of '*(*(c))' prevents parallelization
Accelerator scalar kernel generated
CC 1.0 : 11 registers; 40 shared, 4 constant, 0 local memory bytes
CC 2.0 : 22 registers; 0 shared, 56 constant, 0 local memory bytes
循环显然是并行的,我认为这也可以被编译器检测到。我很好奇如何向pgcc
解释它?
提前致谢。
答案 0 :(得分:4)
我想我找到了答案。关键是使用independent
子句:
#pragma acc data copyin(a[0:SIZE][0:SIZE],b[0:SIZE][0:SIZE]) copy(c[0:SIZE][0:SIZE])
{
# pragma acc region
{
#pragma acc loop independent vector(16)
for (i = 0; i < SIZE; ++i) {
#pragma acc loop independent vector(16)
for (j = 0; j < SIZE; ++j) {
c[i][j] = a[i][j] + b[i][j];
}
}
}
}