CUDA:如何使用 barrier.sync

Posted

技术标签:

【中文标题】CUDA:如何使用 barrier.sync【英文标题】:CUDA: how to use barrier.sync 【发布时间】:2018-12-07 02:40:40 【问题描述】:

我已经阅读了https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#parallel-synchronization-and-communication-instructions-bar关于PTX同步功能的详细信息。

    它说有16个“屏障逻辑资源”,您可以通过参数“a”指定使用哪个屏障。什么是障碍逻辑资源?

    我有一段来自外部来源的代码,我知道它可以工作。但是,我无法理解“asm”中使用的语法以及“memory”的作用。我假设“name”替换“%0”,“numThreads”替换“%1”,但是“memory”是什么,冒号是做什么的?

    __device__ __forceinline__ void namedBarrierSync(int name, int numThreads) 
    asm volatile("bar.sync %0, %1;" : : "r"(name), "r"(numThreads) : "memory");
    

    在一个有 256 个线程的块中,我只希望线程 64 ~ 127 同步。这可能与barrier.sync 功能? (例如,假设我有 1 个块的网格,256 个线程的块。我们将块分成 3 个条件分支 s.t. 线程 0 ~ 63 进入内核 1,线程 64 ~ 127 进入内核 2,线程 128 ~ 255进入内核 3。我希望内核 2 中的线程只在它们之间同步。所以如果我使用上面定义的“namedBarrierSync”函数:“namedBarrierSync(1, 64)”。那么它只同步线程 64 ~ 127,还是线程0~63?

    我已经用下面的代码进行了测试(假设 gpuAssert 是在文件某处定义的错误检查函数)。

代码如下:

__global__ void test(int num_threads) 

    if (threadIdx.x >= 64 && threadIdx.x < 128) 
    
        namedBarrierSync(0, num_threads) ;
    
    __syncthreads();


int main(void) 

    test<<<1, 1, 256>>>(128);
    gpuAssert(cudaDeviceSynchronize(), __FILE__, __LINE_);
    printf("complete\n");
    return 1;

【问题讨论】:

【参考方案1】:
    “屏障逻辑资源”是同步线程块中的线程/扭曲所必需的硬件(可能是原子计数器等)。您无需了解实际的硬件实现即可对其进行编程,知道有 16 个可用实例就足够了。 正如 Robert Crovella 在 Nvidia 论坛上的 cross-post 中指出的那样,内联 PTX 的文档位于 https://docs.nvidia.com/cuda/inline-ptx-assembly/index.html。 barrier.sync 具有命名屏障和 64 线程计数同步到达命名屏障的前两个扭曲(计算能力高达 6.x)或到达命名屏障的前 64 个线程(计算能力 7.0 及以上)。 您的测试只启动了一个线程(分配了 256 字节的共享内存),这使得同步指令的测试没有实际意义。您希望以 test&lt;&lt;&lt;1, 256&gt;&gt;&gt;(128); 的身份启动测试内核。

【讨论】:

以上是关于CUDA:如何使用 barrier.sync的主要内容,如果未能解决你的问题,请参考以下文章

CUDA:如何在 GPU 中将数组的所有元素加总为一个数字?

如何使副本在 nvidia 显卡而不是英特尔集成显卡上运行

如何通过 pytorch 使 Intel GPU 可用于处理?

为什么CUDA程序可以使用CMake“FIND_PACKAGE”,但不能使用“LANGUAGES CUDA”?

Cuda 随机数生成

如何在 dll 中使用 CUDA?