我最近开始学习 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 还充当我的视频卡,我担心这可能会产生奇怪的效果。
提前致谢!