【发布时间】:2012-08-30 16:01:39
【问题描述】:
我最近开始学习 CUDA,我偶然发现了一个我无法理解的非常奇怪的行为。
我的代码本质上是计算一个简单 atomicAdd 内核的平均执行时间。为此,我在循环中调用内核以获得更好的平均值。我将设备内存分配和副本包含在循环中,因为我想将其包含在我的执行时间估计中。问题是,如果循环的运行次数过多,程序通常会失败并出现 Runtime API 错误 30。
我怀疑我的内存访问可能有问题,所以我在程序上运行 memcheck 无济于事。显然没有内存错误。此外,如果只运行内核几次,就没有问题,这似乎也表明内核并不是问题所在。只有连续调用太频繁才会有问题。
我的代码框架如下:
for(int i = 0; i < runs; i++)
{
//////////////////////////////////
// Copy memory from Host to Device
//////////////////////////////////
cutilSafeCallNoSync( cudaMemcpy(dev_waveforms, waveforms, num_wf * wf_length * sizeof(float),
cudaMemcpyHostToDevice) );
cutilSafeCallNoSync( cudaMemcpy(dev_delays, delays, num_wf * sizeof(int),
cudaMemcpyHostToDevice) );
////////////////////////
// Kernel Call
////////////////////////
kernel_wrapper<float>(dev_waveforms, dev_focused, dev_delays,
wf_length, num_wf, threads, blocks, kernel);
//copy back to host memory.
cutilSafeCallNoSync( cudaMemcpy(focused, dev_focused, J * wf_length * sizeof(float),
cudaMemcpyDeviceToHost) );
}
同样,只有在运行足够大时才会失败。还有其他一些奇怪的事情发生了,但我暂时不谈了。
哦,我正在使用 Visual Studio 2010 在 Windows 7 上进行开发。我的 GPU 还充当我的视频卡,我担心这可能会产生奇怪的效果。
提前致谢!
【问题讨论】:
-
在 Windows 下有一个看门狗定时器,它可以在长内核上跳闸。多个没有同步的内核可能会导致相同的问题。查看它是否与时间阈值(例如 30 秒)有关。
-
根据@PaulR 所说,尝试在循环中添加
cudaDeviceSynchronize();。 -
快速更新:我已将看门狗计时器的阈值从默认的 2 设置为 8 秒。我最初认为这有帮助,因为我成功了 8/10 次。但是,我刚刚又试了一次,成功率为0%。不一致使得调试变得困难。尽管如此,这并不能解释更改数组大小如何影响问题。此外,数组的内容似乎也有影响。
标签: cuda