【问题标题】:Simplest way to clear CUDA shared memory between kernel runs在内核运行之间清除 CUDA 共享内存的最简单方法
【发布时间】:2017-01-02 01:27:32
【问题描述】:

我正在尝试在 C-CUDA 中实现箱式过滤器,首先在 CUDA 中实现矩阵平均问题。当我尝试遵循代码而不在 for 循环中注释这些行时,我得到了特定的输出。但是当我评论这些行时,它会再次生成相同的输出!

if(tx==0)
        for(int i=1;i<=radius;i++)
        {
            //sharedTile[radius+ty][radius-i] = 6666.0;
        }

    if(tx==(Dx-1))
        for(int i=0;i<radius;i++)
        {
            //sharedTile[radius+ty][radius+Dx+i] = 7777;
        }

    if(ty==0)
        for(int i=1;i<=radius;i++)
        {
            //sharedTile[radius-i][radius+tx]= 8888;
        }

    if(ty==(Dy-1))
        for(int i=0;i<radius;i++)
        {
            //sharedTile[radius+Dy+i][radius+tx] = 9999;
        }

    if((tx==0)&&(ty==0))
        for(int i=globalRow,l=0;i<HostPaddedRow,l<radius;i++,l++)
        {
            for(int j=globalCol,m=0;j<HostPaddedCol,m<radius;j++,m++)
            {
                //sharedTile[l][m]=8866;
            }
        }

    if((tx==(Dx-1))&&(ty==(Dx-1)))
        for(int i=(HostPaddedRow+1),l=(radius+Dx);i<(HostPaddedRow+1+radius),l<(TILE+2*radius);i++,l++)
        {
            for(int j=HostPaddedCol,m=(radius+Dx);j<(HostPaddedCol+radius),m<(TILE+2*radius);j++,m++)
            {
                //sharedTile[l][m]=7799.0;
            }
        }

    if((tx==(Dx-1))&&(ty==0))
        for(int i=(globalRow),l=0;i<HostPaddedRow,l<radius;i++,l++)
        {
            for(int j=(HostPaddedCol+1),m=(radius+Dx);j<(HostPaddedCol+1+radius),m<(TILE+2*radius);j++,m++)
            {
                //sharedTile[l][m]=9966;
            }
        }

    if((tx==0)&&(ty==(Dy-1)))
        for(int i=(HostPaddedRow+1),l=(radius+Dy);i<(HostPaddedRow+1+radius),l<(TILE+2*radius);i++,l++)
        {
            for(int j=globalCol,m=0;j<HostPaddedCol,m<radius;j++,m++)
            {
                //sharedTile[l][m]=0.0;
            }
        }
    __syncthreads();

你可以忽略那些 for 循环条件和所有,它们现在在这里无关紧要。 可能的基本问题和问题是为什么即使在评论这些行之后我也会得到相同的值?我也尝试在我的主程序和内核中进行一些修改。还输入了手动错误并将其删除,然后再次编译并执行相同的代码,但仍然得到相同的值。有什么办法可以清除 CUDA 中的缓存吗? 我正在使用 Nsight + RedHat + CUDA 5.5。 提前致谢。

【问题讨论】:

    标签: cuda gpgpu gpu


    【解决方案1】:

    为什么即使在评论了这些行之后我也会得到相同的值?

    似乎 sharedTile 在多次连续运行之间指向同一块内存,这是绝对正常的。因此,注释掉的代码不会“生成”任何东西,它只是指向未刷新的同一内存的指针。

    有什么办法可以清除CUDA中的缓存

    我相信你说的是清除共享内存?如果是这样,那么您可以使用here 描述的方法的类比。而不是在主机代码中使用cudaMemset,您将从内核内部清零您的共享内存。最简单的方法是在内核开头放置以下代码,声明sharedTile(这是针对一维线程块,一维共享内存数组):

    __global__ void your_kernel(int count) {
        extern __shared__ float* sharedTile;
        for (int i = threadIdx.x; i < count; i += blockDim.x)
            sharedTile[i] = 0.0f;
        __syncthreads();
        // your code here
    }
    

    以下方法不保证清除共享内存,正如 Robert Crovella 在下面的评论中指出的那样:

    • 或者可能调用nvidia-smi --gpu-reset 参数。
    • the other SO thread 提供了另一种解决方案,其中包括 驱动程序卸载和重新加载。

    【讨论】:

    • 链接方法(“描述的here”,即cudaMemset)不能用于共享内存。 Niether nvidia-smi --gpu-reset 或卸载/重新加载驱动程序都保证对共享内存的内容有任何影响。您建议的所有 3 种清除共享内存的方法都是可疑的。修改共享内存的唯一可靠方法是编写修改共享内存的内核代码。
    • 通过指向“在此处描述”的方法,我没有想到 cudaMemset 的用法。通过将字节显式设置为零来清除共享内存与清除共享内存在高级别的相似,即使这次它是从内核内部设置的。这就是我所说的“你将从内核内部清零你的共享内存”的想法。我会用你的发现更新我的答案,谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-22
    • 2013-03-04
    • 2011-06-29
    • 2022-01-06
    • 2012-03-02
    相关资源
    最近更新 更多