【发布时间】:2011-10-09 19:23:05
【问题描述】:
我在 GeForce GTX 580(费米级)GPU 上面临以下问题。
只是为了给你一些背景知识,我正在读取以以下方式打包在一个文件中的单字节样本:Real(Signal 1)、Imaginary(Signal 1)、Real(Signal 2)、Imaginary(Signal 2)。 (每个字节都是一个有符号字符,取值介于 -128 和 127 之间。)我将它们读入一个 char4 数组,并使用下面给出的内核将它们复制到与每个信号对应的两个 float2 数组中。 (这只是一个更大程序的一个孤立部分。)
当我使用 cuda-memcheck 运行程序时,我会在随机线程和块索引处收到不合格的unspecified launch failure,或者与User Stack Overflow or Breakpoint Hit 或Invalid __global__ write of size 8 一起出现的相同消息。
主内核和启动相关代码复制如下。 奇怪的是,这段代码在我可以访问的非 Fermi 级 GPU 上工作(并且 cuda-memcheck 不会引发错误)。我观察到的另一件事是,对于小于 16384 的N,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 windows 的情况下运行等,但程序行为是相同的。
我在 RHEL 5.6 上使用 CUDA 4.0 驱动程序和运行时(也尝试过 CUDA 3.2)。 GPU计算能力为2.0。
请帮忙!如果有人有兴趣在他们的 Fermi 卡上运行它,我可以发布整个代码。
更新:为了它,我在 pf2FFTInX 和pf2FFTInY 赋值语句之间插入了一个__syncthreads(),并且N = 32768 的内存错误消失了。但是在N = 65536,我仍然遇到错误。<-- 这并没有持续多久。仍然出现错误。
更新:继续奇怪的行为,当我使用 cuda-memcheck 运行程序时,我得到这些 16x16 多色像素块随机分布在我的屏幕上。如果我直接运行程序,则不会发生这种情况。
【问题讨论】:
-
在亲眼目睹了一些 CUDA 巫术之后,我会建议一些看起来/很愚蠢的东西。在内核中声明 2 个本地 float2 var,读取 x 和 y 的值,然后立即将它们写入内存。或者甚至尝试将 char4 值读取到 char4 变量,然后将其写入 float2 变量,然后写入内存。会发生什么?
-
@jmsu:我尝试了你的建议,但行为没有区别。
-
好吧,我猜没有巫毒教。我只能建议你展示你是如何分配内存的,也许它有一些问题。在您发布的代码中,我没有发现任何问题。
-
@jmsu:完成。我还在我的问题中添加了一些我尝试过的其他内容。
-
只是为了记录,它是一张坏卡。换了卡,一切都恢复正常了。