【发布时间】:2015-04-24 18:28:25
【问题描述】:
我几乎要为这个问题扯掉头发了。
我有一个 CUDA 内核,它对存储在 3D 数组中的数据进行一些数学运算。在测试这个时,我曾经为数组分配一些值(非零)并观察结果。从那以后,我注释掉了这些行,但结果仍然相同。就好像它完全忽略了我正在将 memset 设置为 0 的事实。
当我在 Debug 中单步执行代码时,代码可以正常工作...但在 Release 中却不行! 我的猜测是这个矩阵有内存泄漏。
我将此数组分配为:
cudaExtent m_extent = make_cudaExtent(sizeof(float)*matdim.x, matdim.y, matdim.z); // width, height, depth
cudaPitchedPtr m_device;
cudaMalloc3D(&m_device, m_extent);
cudaMemset3D(m_device, 0, m_extent);
我这样循环调用内核:
for (int iter = 0; iter < gpu_iterations; iter++)
{
PF_iteration_kernel<<<grids,threads>>>(m_device, m_extent, matdim);
cudaDeviceSynchronize();
}
之后我释放m_device 倾斜指针:
cudaFree(m_device.ptr);
matdim 只是一个 dim3 持有的矩阵维度。
在内核中,我执行以下操作(好吧,我将所有功能都注释掉了......):
__global__ void PF_iteration_kernel(cudaPitchedPtr mPtr, cudaExtent mExt, dim3 matrix_dimensions)
{
int x = threadIdx.x + blockIdx.x * blockDim.x;
int y = threadIdx.y + blockIdx.y * blockDim.y;
// Find location within the pitched memory
char *m = (char*)mPtr.ptr;
int sof = sizeof(float);
size_t pitch = mPtr.pitch;
size_t slice_pitch = pitch*mExt.height;
char* m_addroff = m + y * pitch + x * sof;
printf("m(%d,%d) is %f \n", x, y, *m_addroff); // display the slice
*m_addroff = 0; // WILL THIS RESET IT?!
__syncthreads();
}
这应该只是显示 0,但它显示了我的旧值(25、26、27、28 等)。
我已经多次清理、重新清理和重建所有东西。我已经重新启动了 IDE。
我的 IDE 是带有 NSight 4.6 (CUDA 7.0) 的 Visual Studio 2010。 我在 Windows 7 x64 上
【问题讨论】:
-
这个之前的 SO 问题有什么相关性吗? stackoverflow.com/questions/10611451/…
-
@WeatherVane,我不这么认为。接受的答案甚至不会释放他们分配的任何内存。我所做的只是一个 Malloc 和一个 Memset,但另一个问题中的人也在询问 Memcpy。
-
在
printf("m(%d,%d) is %f \n", x, y, *m_addroff);中,编译器肯定会看到char并将其提升为int并推入堆栈——而不是将float提升为格式要求的double?因为char* m_addroff不是float并且编译器不会根据格式规范推送 args - 尽管有些编译器会警告问题。 -
有趣!我想我必须在尝试 printf() 之前将
m_addroff类型转换为浮动。否则它必须使用一些旧值?我觉得奇怪的是它找到了一些以前的值来显示。但是,嘿,如果它有效,它就有效。谢谢@WeatherVane :) 如果您想将其发布为答案,我会接受。 (哇……)