我写了一个CUDA程序,我对这个程序有两个问题。
当我调用内核函数时,我知道 block_len 必须&lt; = 1024,但我仍然设置 block_len < / EM> &GT; 1024.当我用cuda-gdb和Nsight调试时,有一个预期的&#34; cudaLaunch返回(0x9)&#34;错误。如果我在没有调试的情况下运行程序,程序运行平稳,计算结果与使用CPU(没有并行性)相同,表明我的计算是正确的。为什么错误的程序可以得到正确的结果?
程序将计算 长度*长度 矩阵A,A的每个元素的计算由一个线程完成,ngridDim设置为(1 ,1)。当 长度 &lt; 32时,
的执行时间kernel <<< (1,1), (length, length) >>>
根据 长度 大小的规律性而变化。当 长度 &gt; 32,内核花费的时间突然减少100-1000次。我首先怀疑我的计时代码是错误的,但经过检查后,我认为没有错误。稍后,我会附上计时代码。导致这样的结果的原因是什么?
dim3 dimBlock(length, length);
dim3 dimGrid(1, 1);
float a2;
cudaEvent_t t1, t2;
cudaEventCreate(&t1);
cudaEventCreate(&t2);
cudaEventRecord(t1, 0);
kernel<<<dimGrid, dimBlock>>>(dev_d, dev_D);
cudaEventRecord(t2, 0);
cudaEventSynchronize(t1);
cudaEventSynchronize(t2);
cudaEventElapsedTime(&a2,t1,t2);
printf("kernel time: %f (ms)\n",a2);
如果length = 32,则内核时间为:
kernel time: 37.341919 (ms)
如果length = 33,则内核时间为:
kernel time: 0.004128 (ms)
我的设备的一些信息:
答案 0 :(得分:1)
您应该提供完整的代码。但是:
可能是正确的结果仍然在上一次运行的内存中。设置length
&gt;时32,那么你有一个非法的内核启动,你的内核将无法运行或产生任何结果。您可以通过在内核启动之前清除输出数据来确认这一点。例如,如果dev_D
包含内核的输出,那么执行以下操作:
cudaMemset(dev_D, 0, length*length*sizeof(dev_D[0]));
kernel<<<dimGrid, dimBlock>>>(dev_d, dev_D);
如果你这样做,并且内核无法运行,你绝对应该在dev_D
中获得0,而不是预期的结果。
当length
参数大于32时,每个块请求超过1024个线程,这在CUDA中是非法的。所以内核不运行(如果要确认这一点,请使用正确的CUDA错误检查。)当内核不运行时,测量的启动时间比内核运行时短得多。