CUDA学习笔记(五)——原子性操作

阅读: 评论:0

CUDA学习笔记(五)——原子性操作

CUDA学习笔记(五)——原子性操作

说明

原子性操作不是所有的显卡都支持的,只有算力在1.1及以上的才支持全局内存的原子操作,只有1.2及以上算力的才支持共享内存上的原子操作。
由于显卡算力高的是低的一个超集,类似可理解为于高算力版本可以向下兼容。同时,在编译代码的时候,可以告诉nvcc编译器需要什么样的版本,nvcc -arch=sm_1.2即需要1.2算力版本的支持。
如果不支持就需要考虑升级硬件了。

原子操作

原子操作的概念是由多部操作构成的一个操作集合,如果执行该操作集合,就必须全部执行,不能执行部分操作。
如:

x++;

定义上述++操作是一个原子操作,其共分为三步:

  1. 读取x
  2. x + 1
  3. 将2中的结果重新赋值给x

那么这三步是不能被打断,熟悉线程编码的可能很好理解,如果线程A和线程B同时对x执行这个操作,是无法保证这三步都是按照顺序执行的。可能出现A先读取x,在进行+1操作时,B线程完成了读取和+1以及写入的操作,A再进行+1赋值操作后,值就不再是我们预想的样子。
而原子操作,就不会出现这样的问题,如果A在执行这个原子操作,B线程会进入阻塞态,只有A全部执行完成后,B才能获取到资源继续执行。

常见的CUDA原子操作,如下表:

函数名释义
atomicAdd(&value, add_num)加法:value = value + add_num
atomicSub(&value, sub_num)减法:value = value + sub_num
atomicExch(&value, num)赋值:value = num
atomicMax(&value, num)求最大:value = max(value, num)
atomicMin(&value, num)求最小:value = min(value, num)
atomicInc(&value, compare)向上计数:如果(value <= compare)则value++,否则value = 0
atomicDec(&value, compare)向下计数:如果(value > compare或value == 0), 则value–,否则value = 0
atomicCAS(&value, compare)比较并交换:如果(value != compare),则value = compare
atomicAnd(&value, add_num)与运算:value = value & num
atomicOr(&value, add_num)或运算 value = value
atomicXor(&value, add_num)异或运算 value = value ^ num

但是CUDA中线程更多,操作相同地址的内存时,因为竞争关系,就变成了一系列线程在排队执行串行化操作。就失去了CUDA并行计算的优势,甚至会比cpu版本的更慢。

可以使用全局内存和共享内存的原子操作结合的方式,在每个block中将需要进行原子操作的变量存入共享内存中。此时发生竞争的线程只是当前block内的线程,多个block是可以并行计算的。
每个block计算完成后,再将block内的临时变量进行原子操作存入全局内存中,得到最终的结果。
例如:
需要统计一个数组中元素分布情况。
可以在block内统计完该block内所有线程应该访问的地址上的数据,再讲所有的block在合并起来,就能得到最终的结果。

由上可知,原子操作会影响程序性能,所以需要谨慎设置代码逻辑,不然会适得其反。


Reference

本文发布于:2024-02-02 07:16:28,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170682938742220.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:原子   学习笔记   操作   CUDA
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23