我正在尝试使用C++中的OpenACC并行化Karatsuba算法的迭代版本。我想问一下如何向量化内部for loop。我的编译器向我显示了有关该循环的以下消息:

526, Complex loop carried dependence of result-> prevents parallelization
     Loop carried dependence of result-> prevents parallelization
     Loop carried backward dependence of result-> prevents vectorization

这里是两个嵌套循环的代码:
#pragma acc kernels num_gangs(1024) num_workers(32) copy (result[0:2*size-1]) copyin(A[0:size],$
{
    #pragma acc loop gang
    for (TYPE position = 1; position < 2 * (size - 1); position++) {
        // for even coefficient add Di/2
        if (position % 2 == 0)
            result[position] += D[position / 2];

        TYPE start = (position >= size) ? (position % size ) + 1  : 0;
        TYPE end = (position + 1) / 2;

        // inner loop: sum (Dst) - sum (Ds + Dt) where s+t=i
        #pragma acc loop worker
        for(TYPE inner = start; inner < end; inner++){
            result[position] += (A[inner] + A[position - inner]) * (B[inner] + B[position - inn$
            result[position] -= (D[inner] + D[position - inner]);
        }
    }
}

实际上,我不确定是否可以对其向量化。但是如果是这样,我将无法意识到自己做错了什么。谢谢

最佳答案

“复杂循环携带的结果依赖性”问题是由于指针混叠造成的。编译器无法确定“结果”指向的对象是否与另一个指针的对象之一重叠。

作为C++扩展,可以将C99“restrict”关键字添加到数组的声明中。这将向编译器断言指针没有别名。

另外,您可以在循环指令上添加OpenACC“independent”子句,以告知编译器循环没有任何依赖性。

请注意,OpenACC不支持数组精简,因此除非修改代码以使用标量,否则您将无法并行化“内部”循环。就像是:

rtmp = result[position];
#pragma acc loop vector reduction(+:rtmp)
    for(TYPE inner = start; inner < end; inner++){
        rtmp += (A[inner] + A[position - inner]) * (B[inner] + B[position - inn$
        rtmp -= (D[inner] + D[position - inner]);
    }
result[position] = rtmp;

08-24 16:59