Multithreading GPU内核如何相互通信?
GPU在用于通用计算时,非常重视SIMD和SIMT的细粒度并行性。它们在具有高运算强度的常规数字运行工作负载上表现最好 尽管如此,为了适用于尽可能多的工作负载,它们还必须能够实现粗粒度MIMD并行,不同的内核在不同的数据块上执行不同的指令流 这意味着GPU上的不同内核在执行不同的指令流后必须彼此同步。他们是怎么做到的 在CPU上,答案是缓存一致性加上一组选择与CAS或LL/SC等通信原语协同工作的通信原语。但据我所知,GPU没有缓存一致性-避免此类开销是它们比CPU效率更高的最大原因 那么,GPU内核使用什么方法彼此同步呢?如果它们如何交换数据的答案是通过写入共享主存,那么它们如何进行同步,以便发送方可以通知接收方何时读取数据 如果答案取决于特定的体系结构,那么我对支持CUDA的现代Nvidia GPU特别感兴趣 编辑:从Booo链接的文档中,我的理解如下: 他们似乎用“流”这个词来表示同步完成的大量工作(包括像SIMD这样的细粒度并行);问题是如何在多个流之间进行同步/通信 正如我猜测的,这比在CPU上要明确得多。他们特别谈到:Multithreading GPU内核如何相互通信?,multithreading,synchronization,nvidia,gpgpu,Multithreading,Synchronization,Nvidia,Gpgpu,GPU在用于通用计算时,非常重视SIMD和SIMT的细粒度并行性。它们在具有高运算强度的常规数字运行工作负载上表现最好 尽管如此,为了适用于尽可能多的工作负载,它们还必须能够实现粗粒度MIMD并行,不同的内核在不同的数据块上执行不同的指令流 这意味着GPU上的不同内核在执行不同的指令流后必须彼此同步。他们是怎么做到的 在CPU上,答案是缓存一致性加上一组选择与CAS或LL/SC等通信原语协同工作的通信原语。但据我所知,GPU没有缓存一致性-避免此类开销是它们比CPU效率更高的最大原因 那么,GP
- 页面锁定内存
- cudaDeviceSynchronize()
- cudaStreamSynchronize(streamid)
- cudaEventSynchronize(事件)
因此,流可以通过将数据写入主存(或L3缓存?)进行通信,CPU上的缓存一致性与之不同,而是内存的锁定页和/或显式同步API。我的理解是,使用CUDA“同步”有几种方法:
- CUDA流(在功能级别):
在整个设备上同步。此外,您还可以使用cudaDeviceSynchronize()
同步特定流,或者使用cudaStreamSynchronize(cudaStream\u t stream)
同步某些流中嵌入的事件cudaEventSynchronize(cudaEvent\u t event)
- 协作组(>CUDA 9.0和>CC 3.0):您可以在组级别进行同步,组可以是一组合并的线程、线程块或跨多个设备的网格。这要灵活得多。使用
(1)
用于当前合并的线程集,或 (2)auto group=cooperative\u groups::coalised\u threads()
对于当前threadblock,您可以在块内进一步定义细粒度组,例如auto group=cooperative\u groups::this\u thread\u block()
,或 (3)auto group\u warp=cooperative\u groups::tiled\u partition(group)
或auto group=cooperative\u groups::this\u grid()
用于跨多个设备的网格 然后,您可以调用auto group=cooperative\u groups::this\u multi\u grid()
进行同步。您需要有一个支持group.sync()
或协作启动
的设备。注意:对于协作组,您已经可以在共享内存中使用协作多设备启动
执行传统的块级同步\uu syncthreads()