5.1 CUDA atomic原子操作


和許多多線程並行問題一樣,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。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM