哪个更好,原子之间的竞争:单个Warp的线程还是不同Warp的线程?

时间:2012-08-07 13:10:13

标签: cuda synchronization gpgpu

哪个更好,原子在单个Warp的线程之间或在一个块中不同Warps的线程之间的竞争(并发)?我认为,当一个warp的线程彼此竞争时,访问共享内存时效果会比不同warp的线程小。相反,通过访问全局内存,一个块的不同warp的线程比单线程的线程竞争的更好,不是吗?

我需要它知道如何更好地解决竞争(并发)以及更好地分隔存储:单线程中的线程之间或warp之间的线程。

顺便说一句,可以说团队__ syncthreads();同步它在一个块中扭曲而不是一个warp的线程?

1 个答案:

答案 0 :(得分:2)

如果块中的大量线程对同一个值执行原子更新,则性能会很差,因为这些线程必须全部序列化。在这种情况下,通常最好让每个线程将其结果写入一个单独的位置,然后在一个单独的内核中处理这些值。

如果warp中的每个线程对同一个值执行原子更新,则warp中的所有线程都在同一个时钟周期内执行更新,因此它们必须在原子更新时进行序列化。这可能意味着warp被调度32次以使所有线程得到服务(非常糟糕)。

另一方面,如果块中每个warp中的单个线程执行相同值的原子更新,则影响将会降低,因为warp对(两个warp调度程序在每个时钟处理两个warp) )当它们在处理管道中移动时,它们在时间上偏移(一个时钟周期)。所以最终只有两个原子更新(两个warp中的每一个都有一个),在一个周期内发出并需要立即序列化。

所以,在第二种情况下,情况更好,但仍然存在问题。原因是,根据共享值的位置,您仍然可以在SM之间进行序列化,这可能非常慢,因为每个线程可能必须等待更新一直到全局内存,或者至少L2,然后回来。有可能以这样的方式重构算法:块中的线程对共享内存(L1)中的值执行原子更新,然后每个块中的一个线程对全局内存中的值执行原子更新(L2 )。

原子操作可以是完整的救生员,但它们往往被CUDA新手过度使用。通常使用并行缩减或并行流压缩算法的单独步骤更好(参见thrust::copy_if)。