Fermi GPU的CUDA程序中出现了内存错误

3

我在GeForce GTX 580(Fermi-class)GPU上遇到了以下问题。

为了让您了解背景,我正在读取以以下方式打包的单字节样本文件:实数(信号1),虚数(信号1),实数(信号2),虚数(信号2)。 (每个字节都是有符号字符,取值范围在-128和127之间。)我将它们读入char4数组中,并使用下面给出的内核将它们复制到对应于每个信号的两个float2数组中。 (这只是更大程序的一个孤立部分。)

当我使用cuda-memcheck运行程序时,我会得到不合格的未指定的启动失败,或者在随机线程和块索引处出现相同的消息,以及用户堆栈溢出或断点命中无效__global__写入大小8

下面再次复制主要内核和与启动相关的代码。奇怪的是,这段代码在我可以访问的非Fermi-class GPU上工作正常(且cuda-memcheck没有抛出错误)。我观察到的另一件事是,当N小于16384时,Fermi没有出现任何错误。

#define N   32768

int main(int argc, char *argv[])
{
    char4 *pc4Buf_h = NULL;
    char4 *pc4Buf_d = NULL;
    float2 *pf2InX_d = NULL;
    float2 *pf2InY_d = NULL;
    dim3 dimBCopy(1, 1, 1);
    dim3 dimGCopy(1, 1);
    ...
    /* i do check for errors in the actual code */
    pc4Buf_h = (char4 *) malloc(N * sizeof(char4));
    (void) cudaMalloc((void **) &pc4Buf_d, N * sizeof(char4));
    (void) cudaMalloc((void **) &pf2InX_d, N * sizeof(float2));
    (void) cudaMalloc((void **) &pf2InY_d, N * sizeof(float2));
    ...
    dimBCopy.x = 1024;  /* number of threads in a block, for my GPU */
    dimGCopy.x = N / 1024;
    CopyDataForFFT<<<dimGCopy, dimBCopy>>>(pc4Buf_d,
                                           pf2InX_d,
                                           pf2InY_d);
    ...
}

__global__ void CopyDataForFFT(char4 *pc4Data,
                               float2 *pf2FFTInX,
                               float2 *pf2FFTInY)
{
    int i = (blockIdx.x * blockDim.x) + threadIdx.x;

    pf2FFTInX[i].x = (float) pc4Data[i].x;
    pf2FFTInX[i].y = (float) pc4Data[i].y;
    pf2FFTInY[i].x = (float) pc4Data[i].z;
    pf2FFTInY[i].y = (float) pc4Data[i].w;

    return;
}

我在我的程序中还发现一件事情,那就是如果我将内核中的任意两个char-to-float赋值语句注释掉,就不会出现内存错误。 我在我的程序中还发现一件事情,那就是如果我注释掉内核中的前两个或后两个char-to-float赋值语句中的一个,就不会出现内存错误。如果我从前两个中注释掉一个 (pf2FFTInX),从后两个中注释掉另一个 (pf2FFTInY),错误仍然会出现,但出现的频率较低。当四个赋值语句都未被注释时,内核使用了6个寄存器,当有两个赋值语句被注释时,使用了5 4 个寄存器。

我尝试了32位工具包代替64位工具包、使用-m32编译器选项进行32位编译、在没有X窗口的情况下运行等,但程序行为始终相同。

我在RHEL 5.6上使用CUDA 4.0驱动程序和运行时 (也尝试过CUDA 3.2)。GPU计算能力为2.0。

请帮帮忙!如果有人有兴趣在他们的Fermi卡上运行它,我可以发布整个代码。

更新:只是为了好玩,在pf2FFTInXpf2FFTInY赋值语句之间插入了一个__syncthreads(),对于N=32768,内存错误就消失了。但是在N=65536时,仍然会出现错误。 <-- 这没有持续很久。仍然出现错误。

更新:继续出现奇怪的行为,当我使用cuda-memcheck运行程序时,屏幕上随机分布着这些16x16个多种颜色像素的块。如果我直接运行程序,则不会发生这种情况。


在亲眼见证了一些 CUDA 巫术之后,我会建议一些看起来/可能很傻的东西。在您的内核中声明 2 个本地 float2 变量,将 x 和 y 的值读取到它们中,然后一次性将它们写入内存。甚至可以尝试将 char4 值读取到 char4 变量中,然后从中写入 float2 变量,再写入内存。会发生什么? - jmsu
@jmsu:我尝试了你的建议,但行为没有任何区别。 - Icarus
好的,那就没有什么神秘的了。我只能建议您展示一下如何分配内存,也许存在一些问题。在您发布的代码中,我没有看到任何错误。 - jmsu
你好!你编译时使用了2.x架构吗?例如:-arch=sm_20。这不会解决你的问题,但我们想确保你编译了该架构以便跟踪你的进度 :)。 祝好! - pQB
1
只是为了记录,这确实是一张坏卡。更换了卡片,一切恢复正常。 - Icarus
显示剩余7条评论
1个回答

2
问题是由于一张不好的GPU卡引起的(详见评论)。[我添加了这个答案来将问题从未回答列表中移除并使其更有用。]

谢谢。我想尽可能降低我们的未回答率(您可以在此处查看:http://stackoverflow.com/tags/cuda/topusers),因为我希望将其作为社区指标进行跟踪。 - harrism

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接