CUDA 是否有可能进行不会导致错误的越界访问?
CUDA is it possible to have out-of-bound access that results in no error?
所以我在 CUDA 中遇到了一个非常奇怪的行为。
我在 GPU 上有多个阵列,假设一个是 float a[100];
我有一个如下所示的函数:
float access(int i) {
if (i >= 100) printf("i is out of bound\n");
if (i+blockDim.x >= 100) printf("i+blockDim.x is out of bound\n");
return a[i] + a[i + blockDim.x];
}
在执行过程中,第二条语句被多次打印。然而,即使我到处都使用 cudaGetLastError()
,函数仍然没有捕获到错误!
程序永远不会崩溃。 nvprof
也没有显示任何错误。
我最好的猜测如下:
float a[100]; // byte 0, 4, 8, ..., 396
...
float z[100]; // byte 400, 404, 408, ...
这意味着当我访问 a[100]
时,我实际上是在访问 z[0]
,所以它不会崩溃。
还有其他可能的原因吗?
编辑:在我的实际程序中越界访问很远,[1000]等cuda-memcheck
可以检测到问题
稍微越界访问数组通常不会导致明显的运行时错误(尽管您的代码仍然可能计算不正确)。 GPU 运行时机制不会测试字节级别的访问有效性。
如果访问越界,最终会遇到运行时错误。
根据我对 CPU 主机代码的经验,同样的说法也是正确的(试试吧)。
正因为如此,在CPU端你可以使用像valgrind
这样的工具来捕捉这样的错误,而在GPU端你可以使用像cuda-memcheck
这样的工具来捕获这样的错误捕获此类错误。
所以我在 CUDA 中遇到了一个非常奇怪的行为。
我在 GPU 上有多个阵列,假设一个是 float a[100];
我有一个如下所示的函数:
float access(int i) {
if (i >= 100) printf("i is out of bound\n");
if (i+blockDim.x >= 100) printf("i+blockDim.x is out of bound\n");
return a[i] + a[i + blockDim.x];
}
在执行过程中,第二条语句被多次打印。然而,即使我到处都使用 cudaGetLastError()
,函数仍然没有捕获到错误!
程序永远不会崩溃。 nvprof
也没有显示任何错误。
我最好的猜测如下:
float a[100]; // byte 0, 4, 8, ..., 396
...
float z[100]; // byte 400, 404, 408, ...
这意味着当我访问 a[100]
时,我实际上是在访问 z[0]
,所以它不会崩溃。
还有其他可能的原因吗?
编辑:在我的实际程序中越界访问很远,[1000]等cuda-memcheck
可以检测到问题
稍微越界访问数组通常不会导致明显的运行时错误(尽管您的代码仍然可能计算不正确)。 GPU 运行时机制不会测试字节级别的访问有效性。
如果访问越界,最终会遇到运行时错误。
根据我对 CPU 主机代码的经验,同样的说法也是正确的(试试吧)。
正因为如此,在CPU端你可以使用像valgrind
这样的工具来捕捉这样的错误,而在GPU端你可以使用像cuda-memcheck
这样的工具来捕获这样的错误捕获此类错误。