【问题标题】:CUDA writes to global memory not seen by other warpsCUDA 写入其他经纱看不到的全局内存
【发布时间】:2019-04-02 13:39:25
【问题描述】:

我试图向刚接触 CUDA 的人解释全局内存。我想出了以下虚拟内核,它阻止其他线程中的其他线程,直到选定的线程将全局变量设置为另一个值:

__global__ void with_sync()
{
    while (threadIdx.x / 32 != 0)
    {
        if (is_done != 0)
        {
            break;
        }
    }

    if (threadIdx.x / 32 == 0)
    {
        is_done = 1;
        printf("I'm done!\n");
    }
}

变量is_done在函数外部声明为__device__ __managed__ int(如果我错了,请纠正我,这意味着变量将驻留在全局内存空间中。

但是,当我像这样执行这个内核(单个块中的 1024 个 1D 线程)时:

with_sync<<<1, 1024>>>();
cudaDeviceSynchronize();

I'm done 按预期打印出来。但是,CUDA 程序并没有终止(我在主机代码中放置了cudaDeviceSynchronize() 以便它等待所有线程)。这让我想知道其他经线是否没有收到 is_done 变量的变化。但是,我知道全局内存意味着可以在设备级别看到该值(即至少,网格中的所有块)。

我的问题如下:CUDA 是否进行了任何缓存/优化,从而导致这种不一致的全局内存视图可能发生?有没有办法从驻留在全局内存中的变量中访问“最新”值?

【问题讨论】:

  • @RobertCrovella 这没有回答为什么它打印出“我完成了”,这意味着它正在运行的任何经纱都执行了前面的指令,即将is_done 变量设置为 1 .
  • @RobertCrovella 有趣。我在 Volta (Tesla V100) 和 Pascal (Tesla P4) GPU 上运行它,它们都以相同的方式运行(打印出 32 个“I'm done”实例并停止)。
  • 是的,volta 问题与您之前的代码示例有关,其中的行为可能会有所不同。 volta 问题与您当前的代码示例无关。

标签: c++ cuda


【解决方案1】:

CUDA 是否有任何缓存/优化导致这种不一致的全局内存视图可能发生?有没有办法从驻留在全局内存中的变量中访问“最新”值?

是的,有缓存行为。你可以用volatilequalifier修改它。

这是一个有效的例子:

$ cat t310.cu
#include <stdio.h>

#ifndef USE_VOLATILE
__device__ __managed__ int is_done = 0;
#else
__device__ volatile __managed__ int is_done = 0;
#endif

__global__ void with_sync()
{
    while (threadIdx.x / 32 != 0)
    {
        if (is_done != 0)
        {
            break;
        }
    }

    if (threadIdx.x / 32 == 0)
    {
        is_done = 1;
        printf("I'm done!\n");
    }
}



int main(){

  with_sync<<<1,1024>>>();
  cudaDeviceSynchronize();
}
$ nvcc -o t310 t310.cu
$ ./t310
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
^C
$ nvcc -o t310 t310.cu -DUSE_VOLATILE
$ ./t310
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
I'm done!
$

(如果不清楚上面的第一次运行由于挂起而被 Ctrl-C 终止)

特斯拉 P100 PCIE CUDA 10.0、CentOS 7

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-05
    • 1970-01-01
    • 2018-08-18
    相关资源
    最近更新 更多