欢迎光临散文网 会员登陆 & 注册

CUDA C 学习笔记_1.0.8

2023-06-28 17:53 作者:上岸的小浣熊  | 我要投稿

原子操作

       CUDA的原子操作可以理解为:对变量的 “读取-修改-写入” 这三个操作进行捆绑或锁定,成为最小执行单位,不允许分解和打断。例如:当一个线程对某一个变量执行 “读取-修改-写入” 的操作时,此时第二个线程也需要对同一个变量执行 “读取-修改-写入” 的操作:

       (1) 在不进行原子操作时,如果第二个线程读取时第一个线程还未写入,则读取和第一个线程相同的值,如果第一个线程已经写入完成,就会读取第一个线程写入的值,导致计算出现错误。

       (2) 添加原子操作之后,如果在第一个线程操作完成之前,第二个线程的操作会被阻止,不允许其 “读取-修改-写入” ,只有等带没有线程操作该变量时才被允许。所以第二个线程只会读取到第一个线程写入的值。

       基于这个机制,原子操作实现了对在多个线程间共享的变量的互斥保护,确保任何一次对变量的操作的结果的正确性。CUDA 中的原子操作与共享内存具有一些相似之处,都会使原本互不影响的各个线程之间产生依赖和相互作用。所不同的是,共享内存是 “ 线程块 ” 级别的,对于处于不同线程块之中的两个线程,依然不会因为共享内存的存在而产生相互作用;而原子操作是全局的,针对的是核函数启动时所唤醒的全部线程。

       另外,从某种意义上讲,共享内存的使用初衷是为了提高计算效率,实现多个线程对重复数据的快速访问;原子操作更多的是为了保证计算结果正确的同时,避免 host (主机端) 的介入,在一定程度上会降低计算效率。

原子函数的使用

原子操作通过原子函数实现,常用的原子函数主要有以下几种:

(1) 加法

atomicAdd(&value, num); -----------value = value + num

(2) 减法

atomicSub(&value, num); -----------value = value - num

(3) 赋值

atomicExch(&value, num); ----------value = num

(4) 最大值

atomicMax(&value, num); -----------value = max(value, num)

(5) 最小值

atomicMin(&value, num); ------------value = max(value, num)

       原子函数虽然目前功能比较有限,但其不仅可以使用在 ”线程块“ 级别,还可以使用在整个设备端的全局内存范围,并且最新的 CUDA 计算还可以实现整个计算域 (CPU+GPU) 级别的原子操作。

CUDA C 学习笔记_1.0.8的评论 (共 条)

分享到微博请遵守国家法律