当提供的地址驻留在块共享内存中时,原子操作如何执行?在原子操作期间,它是否会暂停块内其他线程对同一共享内存库的访问,或者停止其他线程执行任何指令,甚至停止所有块中的线程,直到原子操作完成?
2 回答
更新:自 Maxwell(Kepler 之后的一代)以来,NVIDIA 已包含对共享内存中原子操作的硬件支持。争用(即,如果多个线程试图在同一个共享内存位置上操作)会降低性能,这与如果在前 Maxwell 锁上存在争用,软件必须执行的循环不同。
麦克斯韦前:
共享内存硬件包括 1024 个锁。如果调用对共享内存进行操作的原子内在函数,编译器会发出一个短循环来获取并有条件地释放锁,或者如果未获取锁则循环。因此,性能可能非常依赖数据:如果一个 warp 中的所有 32 个线程都尝试获取不同的锁,它们都将执行它们的原子操作并释放锁而根本不循环。另一方面,如果一个 warp 中的所有 32 个线程都试图获取相同的锁,那么当每个线程执行其原子操作并释放所有其他线程试图获取的锁时,warp 将循环 31 次。
获得的锁由共享内存地址的第 2-11 位决定。因此,与 CUDA 中的大多数内存操作一样,对连续 32 位地址进行操作通常会提供良好的性能。
从 CUDA_C_Programming_Guide.pdf (CUDA SDK v5.0) 中的 B.11 Atomic Functions 部分:“......在操作完成之前,没有其他线程可以访问此地址。”
你的问题可以概括为:
执行原子操作:
- 停止块中的所有线程,或
- 仅当所有线程尝试访问原子操作正在使用的内存时才停止所有线程,或者
- 停止所有线程(在所有块中)?
我的猜测是 2:如果线程试图访问被活动原子操作锁定的内存,它们就会停止。
您可以通过编写计时器值来调查正在发生的事情,然后处理它们以确定阻塞行为。抱歉,我没有确定的答案。