和许多多线程并行问题一样,CUDA也存在互斥访问的问题,即当一个线程改变变量X,而另外一个线程在读取变量X的值,执行原子操作类似于有一个自旋锁,只有等X的变量在改变完成之后,才能执行读操作,这样可以保证每一次读取的都是最新的值.

在kernel 程序中,做统计累加,都需要使用原子操作:atomicAdd();

原子操作很明显的会影响程序性能,所以可以的话,尽可能避免原子操作.

CUDA原子操作API:

C.1.1  atomicAdd()
int atomicAdd(int* address, int val);
unsigned int atomicAdd(unsigned int* address,
                           unsigned int val);
unsigned long long int atomicAdd(unsigned long long int* address,
                                        unsigned long long int val);

读取位于全局或共享存储器中地址address 处的32 位或64 位字old,计算(old + val),并将结果存储在存储器的同一地址中。这三项操作在一次原子事务中执行。该函数将返回old。

只有全局存储器支持64 位字。

C.1.2  atomicSub()
int atomicSub(int* address, int val);
unsigned int atomicSub(unsigned int* address,
                           unsigned int val);

读取位于全局或共享存储器中地址address 处的32 位字old,计算(old - val),并将结果存储在存储器的同一地址中。这三项操作在一次原子事务中执行。该函数将返回old。

C.1.3  atomicExch()
int atomicExch(int* address, int val);
unsigned int atomicExch(unsigned int* address,
                            unsigned int val);
unsigned long long int atomicExch(unsigned long long int* address,
                                        unsigned long long int val);
float atomicExch(float* address, float val);
读取位于全局或共享存储器中地址address 处的32 位或64 位字old,并将val 存储在存储器的同一地址中。这两项操作在一次原子事务中执行。该函数将返回old。

只有全局存储器支持64 位字。

C.1.4  atomicMin()
int atomicMin(int* address, int val);
unsigned int atomicMin(unsigned int* address,
                           unsigned int val);
读取位于全局或共享存储器中地址address 处的32 位字old,计算old 和val 的最小值,并将结果存储在存储器的同一地址中。这三项操作在一次原子事务中执行。该函数将返回old。

C.1.5  atomicMax()
int atomicMax(int* address, int val);
unsigned int atomicMax(unsigned int* address,
                           unsigned int val);
读取位于全局或共享存储器中地址address 处的32 位字old,计算old 和val 的最大值,并将结果存储在存储器的同一地址中。这三项操作在一次原子事务中执行。该函数将返回old。

C.1.6  atomicInc()
unsigned int atomicInc(unsigned int* address,
                       unsigned int val);
读取位于全局或共享存储器中地址address 处的32 位字old,计算 ((old >= val) ? 0 : (old+1)),并将结果存储在存储器的同一地址中。这三项操作在一次原子事务中执行。该函数将返回old。

C.1.7  atomicDec()
unsigned int atomicDec(unsigned int* address,
                           unsigned int val);
读取位于全局或共享存储器中地址address 处的32 位字old,计算 (((old == 0) | (old > val)) ? val : (old-1)),并将结果存储在存储器的同一地址中。这三项操作在一次原子事务中执行。该函数将返回old。

C.1.8  atomicCAS()
int atomicCAS(int* address, int compare, int val);
unsigned int atomicCAS(unsigned int* address,
                           unsigned int compare,
                           unsigned int val);
unsigned long long int atomicCAS(unsigned long long int* address,
                                       unsigned long long int compare,
                                       unsigned long long int val);
读取位于全局或共享存储器中地址address 处的32 位或64 位字old,计算 (old == compare ? val : old),并将结果存储在存储器的同一地址中。这三项操作在一次原子事务中执行。该函数将返回old(比较并交换)。

只有全局存储器支持64 位字。

C.2  位逻辑函数C.2.1  atomicAnd()
int atomicAnd(int* address, int val);
unsigned int atomicAnd(unsigned int* address,
                           unsigned int val);
读取位于全局或共享存储器中地址address 处的32 位字old,计算 (old & val),并将结果存储在存储器的同一地址中。这三项操作在一次原子事务中执行。该函数将返回old。

C.2.2  atomicOr()
int atomicOr(int* address, int val);
unsigned int atomicOr(unsigned int* address,
                          unsigned int val);
读取位于全局或共享存储器中地址address 处的32 位字old,计算 (old | val),并将结果存储在存储器的同一地址中。这三项操作在一次原子事务中执行。该函数将返回old。

C.2.3  atomicXor()
int atomicXor(int* address, int val);
unsigned int atomicXor(unsigned int* address,
                           unsigned int val);
读取位于全局或共享存储器中地址address 处的32 位字old,计算 (old ^ val),并将结果存储在存储器的同一地址中。这三项操作在一次原子事务中执行。该函数将返回old。

5.1 CUDA atomic原子操作的更多相关文章

  1. CUDA atomic原子操作

    CUDA的原子操作可以理解为对一个变量进行"读取-修改-写入"这三个操作的一个最小单位的执行过程,这个执行过程不能够再分解为更小的部分,在它执行过程中,不允许其他并行线程对该变量进 ...

  2. 并发之java.util.concurrent.atomic原子操作类包

    15.JDK1.8的Java.util.concurrent.atomic包小结 14.Java中Atomic包的原理和分析 13.java.util.concurrent.atomic原子操作类包 ...

  3. C++11开发中的Atomic原子操作

    C++11开发中的Atomic原子操作 Nicol的博客铭 原文  https://taozj.org/2016/09/C-11%E5%BC%80%E5%8F%91%E4%B8%AD%E7%9A%84 ...

  4. goalng-sync/atomic原子操作

    目录 1.go已经提供了锁,为什么还需要atomic原子操作? 2.atomic原子操作为什么比mutex快? 3.CAS 4.互斥锁与原子操作区别 5.原子操作方法 5.1 atomic.AddIn ...

  5. atomic 原子操作

    原子操作:操作仅由一个独立的CPU指令代表和完成.保证并发环境下原子操作的绝对安全 标准库代码包:sync/atomic atomic是最轻量级的锁,在一些场景下直接使用atomic包还是很有效的 C ...

  6. 深入理解Atomic原子操作和volatile非原子性

    原子操作可以理解为: 一个数,很多线程去同时修改它,不加sync同步锁,就可以保证修改结果是正确的 Atomic正是采用了CAS算法,所以可以在多线程环境下安全地操作对象. volatile是Java ...

  7. atomic原子操作

    C++中对共享数据的存取在并发条件下可能会引起data race的未定义行为,需要限制并发程序以某种特定的顺序执行,有两种方式:1.使用mutex保护共享数据: 2.原子操作 原子操作:针对原子类型操 ...

  8. 深入理解java:2.3.1. 并发编程concurrent包 之Atomic原子操作(循环CAS)

    java中,可能有一些场景,操作非常简单,但是容易存在并发问题,比如i++, 此时,如果依赖锁机制,可能带来性能损耗等问题, 于是,如何更加简单的实现原子性操作,就成为java中需要面对的一个问题. ...

  9. atomic 原子操作的类

    import java.util.concurrent.atomic.AtomicInteger; /** * 原子操作的类 atomic */ public class VolatileDemo { ...

随机推荐

  1. 用JavaScript获取页面上被选中的文字的技巧

    这里介绍的一个小技巧是如何用JavaScript获取页面上被选中的文字的方法.最关键的JavaScript API是: event.selection = window.getSelection(); ...

  2. eval()字符串转成对象

    var s = "{a:1,b:2}"; console.log(typeof s); s = eval("(" + s + ")"); c ...

  3. 认识OD的两种断点

    OllyDBG从原理上来区分,有两种不同的断点:软件断点和硬件断点. 也许会有朋友说那不是还有内存断点吗? 内存断点严格来说是属于一种特殊的软件断点. 内存断点: 内存断点每次只能设置一个,假如你设置 ...

  4. ECNU-2574 Principles of Compiler

    题意: 给出编译规则,求是否满足条件 A:= '(' B')'|'x'.    B:=AC.    C:={'+'A}. 其中{}表示里面的内容可以出现0次或者多次 注意点见代码注释 #include ...

  5. 【NOIP 2016 总结】

    距离杯赛已经很久了,然而我现在才打总结.. 我好惨的说..两场才380... DAY 1 第一题 toy 送分题,模拟的时候+一下再mod一下就好. [当时打完这题就没再看一眼了,好方的说] #inc ...

  6. Java知识大全

    http://blog.csdn.net/zhangerqing/article/details/8245560

  7. java List 去重(两种方式)

    方法一: 通过Iterator 的remove方法 Java代码  public void testList() { List<Integer> list=new ArrayList< ...

  8. php Ajax 局部刷新

    php Ajax 局部刷新: HTML部分 </head> <body> <h1>Ajax动态显示时间</h1> <input type=&quo ...

  9. 转:tar 常用命令

    tar在linux上是常用的打包.压缩.加压缩工具,他的参数很多,折里仅仅列举常用的压缩与解压缩参数 参数: -c :create 建立压缩档案的参数: -x : 解压缩压缩档案的参数: -z : 是 ...

  10. Android安全问题 抢先拦截短信

    同上篇文章一样,这里只陈述结果,代码分析稍后给出 导读:本文叙述如何先于某些伪杀毒软件.病毒.常规软件获取到短信 众所周知,android系统在收到短信息的时候会发送广播,但是此广播是有序广播,也就是 ...