CUDA學習(四)之使用全局內存進行歸約求和(一個包含N個線程的線程塊)


問題:使用CUDA進行數組元素歸約求和,歸約求和的思想是每次循環取半。

詳細過程如下:

  假設有一個包含8個元素的數組,索引下標從0到7,現通過3次循環相加得到這8個元素的和,使用一個間隔變量,該間隔變量隨循環次數改變(累乘)。

  第一次循環,間隔變量stride等於1,將0與1號元素、2與3號元素、4與5號元素、6與7號元素相加並將結果分別保存在0、2、4、6號元素中(圖中紅色框所示)。

  第二次循環,間隔變量stride等於2,將0與2號元素、4與6號元素相加並將結果分別保存在0、4號元素中(圖中紅色框所示)。

  第三次循環,間隔變量stride等於4,將0與4號元素相加並將結果保存在0號元素中(圖中紅色框所示)。

  三次循環過后,整個數組元素相加之和就保存在數組0號元素中。

 

代碼如下:

#pragma once #include "cuda_runtime.h" #include "device_launch_parameters.h" #include "device_functions.h" #include <iostream> using namespace std; const int N = 128; //數組長度  __global__ void d_ParallelTest(double *Para) { int tid = threadIdx.x;
//----隨循環次數的增加,stride逐次翻倍(乘以2)----------------------------------------------------- for (int stride = 1; stride < blockDim.x; stride *= 2) { if (tid % (2 * stride) == 0) { Para[tid] += Para[tid + stride];          //對應上圖中紅色框的元素 } __syncthreads(); } } void ParallelTest() { double *Para; cudaMallocManaged((void **)&Para, sizeof(double) * N); //統一內存尋址,CPU和GPU都可以使用的數組 double ParaSum = 0; for (int i = 0; i<N; i++) { Para[i] = (i + 1) * 0.1;   //數組賦值 ParaSum += Para[i]; //CPU端數組累加 } cout << " CPU result = " << ParaSum << endl;   //顯示CPU端結果 double d_ParaSum; d_ParallelTest << < 1, N >> > (Para);   //調用核函數(一個包含N個線程的線程塊) cudaDeviceSynchronize();   //同步 d_ParaSum = Para[0];   //從累加過后數組的0號元素得出結果 cout << " GPU result = " << d_ParaSum << endl; //顯示GPU端結果 } int main() { //並行歸約 ParallelTest();                       //調用歸約函數 system("pause"); return 0; }

結果如下所示(CPU和GPU計算結果一致):

 


免責聲明!

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



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