CUDA:如何在指向数组的指针数组上应用限制?

CUDA:如何在指向数组的指针数组上应用限制?,cuda,restrict-qualifier,Cuda,Restrict Qualifier,此内核使用两个\uuuuu restrict\uuuuint数组,可以很好地编译: __global__ void kerFoo( int* __restrict__ arr0, int* __restrict__ arr1, int num ) { for ( /* Iterate over array */ ) arr1[i] = arr0[i]; // Copy one to other } 但是,组成指针数组的相同两个int数组编译失败: __global__

此内核使用两个
\uuuuu restrict\uuuu
int数组,可以很好地编译:

__global__ void kerFoo( int* __restrict__ arr0, int* __restrict__ arr1, int num )
{
    for ( /* Iterate over array */ )
        arr1[i] = arr0[i];  // Copy one to other
}
但是,组成指针数组的相同两个int数组编译失败:

__global__ void kerFoo( int* __restrict__ arr[2], int num )
{
    for ( /* Iterate over array */ )
        arr[1][i] = arr[0][i];  // Copy one to other
}
编译器给出的错误是:

error: invalid use of `restrict'

我有一些结构,它们是由指向数组的指针数组组成的。(例如,传递到具有
int*arr[16]
的内核的结构)如何将它们传递到内核并能够对其应用
\uuuu restrict\uuu

CUDA C手册仅参考了C99对
\uu restrict\uu
的定义,没有特殊的CUDA特定情况

由于指示的参数是一个包含两个指针的数组,因此
\uuuuu restrict\uuuu
的使用在我看来非常有效,编译器没有理由抱怨IMHO。我会要求编译器作者验证并可能/可能纠正这个问题。不过,我会对不同的观点感兴趣

对@talonmies的一句评论:

restrict的要点是告诉编译器两个或多个指针参数在内存中永远不会重叠


严格来说,这不是事实
restrict
告诉编译器,在指针的生命周期内,该指针是唯一可以访问指向对象的指针。请注意,指向的对象仅假定为
int
的数组。(事实上,在本例中只有一个
int
)由于编译器无法知道数组的大小,因此应由程序员来保护数组的边界。

通过一些任意迭代在代码中填充注释,我们得到以下程序:

__global__ void kerFoo( int* __restrict__ arr[2], int num )
{
    for ( int i = 0; i < 1024; i ++)
        arr[1][i] = arr[0][i];  // Copy one to other
}
\uuuuu全局\uuuuuu无效kerFoo(int*\uuuuu限制\uuuuuuu arr[2],int num)
{
对于(int i=0;i<1024;i++)
arr[1][i]=arr[0][i];//将一个复制到另一个
}

这与CUDA 10.1(Godbolt.org)一起使用。

\uuuuuu restrict\uuuuu
对于指针来说确实很有用,但是
int*arr[2]
实际上是一个数组,如果两个点。我认为,主机代码无法……限制实际上是给您带来了一些性能好处??第二次使用
\uuuuuu Restrict\uuuu
毫无意义。
\uuuuu restrict\uuuu
的全部要点是告诉编译器,两个或多个指针参数在内存中永远不会重叠。在这种情况下,您没有两个指针参数,因此
\uuuuuu restrict\uuuuu
不适用。为什么不
int*\uuuuuuu restrict\uuuuu restrict\uuuuuu
?不过,这可能有些过分。您可能只需要
int*\u\u restrict\u*arr