CUDA 中大小为 4 的非法写入

Posted

技术标签:

【中文标题】CUDA 中大小为 4 的非法写入【英文标题】:Illegal write of size 4 in CUDA 【发布时间】:2012-10-16 10:16:43 【问题描述】:

当我使用 cuda-gdb 为特定输入运行它时,我编写了一个由于设备非法地址而面临内核启动失败的代码。我使用 cuda-memcheck 运行它并得到 Invalid write of size 4 错误。代码太大,所以我将在这里解释场景。

我有一个主内核,我将一个用作堆栈的数组指针传递给它。 我有一个从主内核调用并使用堆栈的设备函数。

__device__ void find(int v , int* p, int* pv,int n, int* d_stackContents)


    int d_stackTop;
    d_stackTop = -1;
    *pv = p[v];
    if(*pv == -1)
            *pv = v;

    
    else
    cuPrintf("Stack top is %d\n",d_stackTop);
    d_stackTop = d_stackTop + 1;
    d_stackContents[d_stackTop] = v;
    cuPrintf("Stack top is %d\n",d_stackTop);
    while(*pv != -1)
            d_stackTop = d_stackTop + 1;
            d_stackContents[d_stackTop] = *pv;
            cuPrintf("Stack top is %d\n",d_stackTop);
            *pv = p[*pv];
    


错误发生在 d_stackContents[d_stackTop] = *pv;

我在主内核中调用设备函数如下:

find(v[idx], p,&pv,n, d_stackContents);

其中 idx = threadIdx.x + blockDim.x * blockIdx.x 并且我已将 pv 声明为 int pv;

此外,d_stackContents 数组使用 cudaMalloc 在 main 中分配,并作为参数传递给主内核

【问题讨论】:

【参考方案1】:

除非您在单个块中使用单个线程调用内核,否则这将不起作用。否则,所有线程都会在彼此的堆栈上乱涂乱画。如果您随后取消引用存储在损坏堆栈上的指针,它将立即解释为什么您的代码会尝试访问非法地址。

您需要为每个线程使用单独的堆栈,或者在全局内存中使用具有堆栈指针的单个堆栈,该堆栈指针仅通过原子操作进行操作。

【讨论】:

以上是关于CUDA 中大小为 4 的非法写入的主要内容,如果未能解决你的问题,请参考以下文章

使用存储在另一个数组中的数组索引时,Cuda 非法内存访问错误

简单cuda内核添加:2432内核调用后内存非法

MySQL 查询错误“非法小时值”导致 Google Apps 脚本中出现循环和写入问题

InvalidKeyException 非法密钥大小

模式匹配中的非法位大小

遇到非法内存访问