繁体   English   中英

为什么我的CUDA内核返回旧值?

[英]Why is my CUDA kernel returning old values?

几乎就是在这个问题上撕掉我的头发。

我有一个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的Visual Studio 2010(CUDA 7.0)。 我在Windows 7 x64上

考虑一下

char* m_addroff = m + y * pitch + x * sof;
printf("m(%d,%d) is %f \n", x, y, *m_addroff);

编译器将看到一个char并将其推送到int推入堆栈 - 而不是将float提升为格式所需的double

编译器不提供适合格式规范的参数,但是一些编译器将检查格式规范并警告问题。

我建议你抛出这个论点。 我冒险猜测和失败,但这样的事情

printf("m(%d,%d) is %f \n", x, y, *(float*)m_addroff);

Herer是一个简单的例子。

#include <stdio.h>
int main()
{
    char car [4] = {0};
    char *cptr = car;
    printf ("Hello %f\n", *(float*)cptr);
    return 0;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM