5 1 CUDA atomic原子操作

2021-09-07 23:16:09 字數 3506 閱讀 7065

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

CUDA atomic原子操作

cuda的原子操作可以理解為對乙個變數進行 讀取 修改 寫入 這三個操作的乙個最小單位的執行過程,這個執行過程不能夠再分解為更小的部分,在它執行過程中,不允許其他並行執行緒對該變數進行讀取和寫入的操作。基於這個機制,原子操作實現了對在多個執行緒間共享的變數的互斥保護,確保任何一次對變數的操作的結果的...

CUDA atomic原子操作

cuda的原子操作可以理解為對乙個變數進行 讀取 修改 寫入 這三個操作的乙個最小單位的執行過程,這個執行過程不能夠再分解為更小的部分,在它執行過程中,不允許其他並行執行緒對該變數進行讀取和寫入的操作。基於這個機制,原子操作實現了對在多個執行緒間共享的變數的互斥保護,確保任何一次對變數的操作的結果的...

通過muduo的Atomic h學習原子操作

最新在讀muduo原始碼,想寫乙個原始碼閱讀的系列,就以這個為開篇吧 原始碼如下 templateclass atomicintegert noncopyable uncomment if you need copying and assignment atomicintegert const at...