CUDA之並行演算法系列(一)樹狀加法

2021-07-29 10:37:30 字數 2124 閱讀 5578

我們傳統的加法 a + b + c + d ,只能在乙個執行緒上進行,但是我們也很容易想到,如果把加法分成多步執行,比如先算 a+b,c+d,再把他們的結果相加,通過這樣的方式我們就可以把任務分開,也就是可以並行了,這就是樹狀加法:

通過這種方式我們就可以把256個數的加法進行並行了。

上圖是樹狀加法的乙個示意圖,示意圖中第一排每乙個格仔就是乙個執行緒的結果,儲存在shared,暫且把shared[0]簡寫為 sh0,我們可以清楚的看到計算的過程:

sh0=sh0+sh1, sh2=sh2+sh3, sh4=sh4+sh5...

同步sh0=sh0+sh2;sh4=sh4+sh6...

同步...

最後結果在sh0裡

其實樹狀加法可以寫成乙個很簡單的while迴圈:

while(offset

< thread_num)

offset += offset;

mask = offset + mask;

__syncthreads(); }

下面我們就來看看這個while迴圈:

注意& 按位「與」,只有1&1 = 1

tid=0時,mask = 1,0&1=0,所以shared[0] = sh0 + sh1,完成第一步的前兩個相加。

tid=1時,mask = 1,1&1=1,不作運算。

tid=2時,mask = 1,10&01 = 00,所以shared[2] = sh2 + sh3

tid=3時,mask = 1,11&01 = 01,不作運算。

可以看出來這是第一層的計算

同步之後第二層:

offset=1+1=2,mask=2+1=3;

tid=0時,mask = 3,0&11=0,所以shared[0] = sh0 + sh2,完成第二步的前兩個相加。

tid=1時,mask = 3,1&11=1,不作運算。

tid=2時,mask = 3,10&11 = 10,不作運算。

tid=3時,mask = 3,11&11 = 01,不作運算。

tid=4時,mask = 3,100&011 = 000,所以shared[4] = sh4 + sh6

後面都以此類推,直到offset 大於等於執行緒數就跳出了

if(tid == 0)
核函式:

// __global__ 函式 (gpu上執行) 計算立方和

__global__ static

void sumofsquares(int *num, int* result, clock_t* time)

//同步 保證每個 thread 都已經把結果寫到 shared[tid] 裡面

__syncthreads();

//樹狀加法

int offset = 1, mask = 1;

while (offset < thread_num)

offset += offset;

mask = offset + mask;

__syncthreads();

}//計算時間,記錄結果,只在 thread 0(即 threadidx.x = 0 的時候)進行,每個 block 都會記錄開始時間及結束時間

if (tid == 0)

}

執行結果:

我們看到比起上一次沒用樹狀加法的144185個週期,這次只用了133738個週期,總的來說這個結果還是非常不錯的,甚至和完全不在gpu上加和的程式速度差不多,這是因為,在完全不在 gpu 上進行加總的版本,寫入到 global memory 的資料數量很大(8192 個數字),這對效率也會有影響。所以,這一版程式不但在 cpu 上的運算需求降低,在 gpu 上也能跑的更快~

樹狀陣列求逆序對 演算法系列之 陣列中的逆序對

題目 劍指offer 01 題目描述在陣列中如果前乙個數字大於後乙個數字,則稱為這個數字組合組成乙個逆序對。輸入乙個陣列,求所有的逆序對的總數。如 陣列 則它的逆序對是 7,5 7,6 7,4 5,4 6,4 總共有五個。02 解法1 類似的題目,我們的第一反應都是,固定乙個數,如7,然後從後面的數...

一臉懵逼的演算法系列之漢諾塔

法國數學家愛德華 盧卡斯曾編寫過乙個印度的古老傳說 在世界中心貝拿勒斯 在印度北部 的聖廟裡,一塊黃銅板上插著三根寶石針。印度教的主神梵天在創造世界的時候,在其中一根針上從下到上地穿好了由大到小的64片金片,這就是所謂的漢諾塔。不論白天黑夜,總有乙個僧侶在按照下面的法則移動這些金片 一次只移動一片,...

白話經典演算法系列之十七 陣列中只出現一次的數

白話經典演算法系列之十七 陣列中只出現一次的數 歡迎關注微博 首先看看題目要求 陣列 a中,除了某乙個數字 x之外,其他數字都出現了三次,而 x出現了一次。請給出最快的方法找到x。這個題目非常有意思,在本人部落格中有 位操作基礎篇之位操作全面總結 這篇文章介紹了使用位操作的異或來解決 陣列中其他數字...