各个线程的全局内存访问

时间:2018-05-03 19:36:43

标签: cuda gpgpu raytracing

我正在写一个简单的光线跟踪器。这个想法是,对于每个像素,都有一个遍历全局存储器中某个结构(几何)的线程。

我这样调用我的内核:

trace<<<gridDim, blockDim>>>(width, height, frameBuffer, scene)

其中scene是先前使用cudaMalloc分配的结构。每个线程必须从同一节点开始遍历此结构,并且很可能许多并发线程将尝试多次读取相同的节点。这是否意味着当这种读取发生时,它会削弱并行度?

鉴于几何体很大,我认为复制它不是一种选择。我的意思是整个过程仍然发生得相当快,但我想知道它是否是必须要处理的东西,或者只是简单地留在微风中。

3 个答案:

答案 0 :(得分:1)

首先,当你说并发读取可能会或可能不会削弱并行度时,我认为你的想法是错误的。因为这就是平行的意思。每个线程同时读取。相反,当每个线程基本上需要相同的东西,即同一节点时,你应该考虑它是否会影响性能,因为更多的内存访问。

根据文章here,如果数据位置存在且仅在warps中,则可以合并内存访问。

这意味着如果warp中的线程试图访问彼此靠近的内存位置,则可以将它们合并。在您的情况下,每个线程都尝试访问“相同”节点,直到它遇到分支的端点。

这意味着内存访问将在warp中合并,直到线程分支为止。

答案 1 :(得分:0)

从每个线程有效访问全局内存取决于您的设备架构和代码。全局内存上分配的数组由CUDA驱动程序与256字节内存段对齐。设备可以通过与其大小对齐的32,64或128字节事务访问全局内存。该设备将由warp线程发出的全局内存加载和存储合并到尽可能少的事务中,以最小化DRAM带宽。计算能力小于2.0的设备的未对齐数据访问会影响访问数据的有效带宽。使用计算能力为&gt;的设备时,这不是一个严重的问题。 2.0。话虽如此,无论您的设备生成如何,当访问具有大步幅的全局内存时,有效带宽变差(Reference)。我认为对于随机访问,可能会出现相同的行为。

答案 2 :(得分:-1)

除非你在阅读时没有改变结构,我假设你这样做(如果它是一个你可能渲染每一帧的场景?)然后是的,它会削弱性能并可能导致不确定的行为。这被称为竞争条件。您可以使用原子操作来克服此类问题。使用原子操作可以保证竞争条件不会发生。  你可以试试,填充场景&#39;如果你能适应共享内存。  您还可以尝试使用流来增加并发性,这也会为在同一个流中运行的内核带来某种同步。