簡體   English   中英

CUDA和線程阻塞開銷

[英]CUDA and thread blocks overhead

我已經實現了一個計算矩陣乘法的簡單內核。 這是代碼:

__global__ void MatMultKernel(Mat A, Mat B, Mat C){

int i;
double val=0.0;
int ix=blockDim.x*blockIdx.x+threadIdx.x;  
int iy=blockDim.y*blockIdx.y+threadIdx.y;
if(ix<A.nrows && iy<B.nrows){
    for(i=0;i<A.nrows;i++)
        val+=A.value[iy*A.nrows+i]*B.value[i*B.nrows+ix];
    C.value[iy*C.nrows+ix]=val;
 }
}

我通過改變線程和塊配置來測量這個內核的運行時間。

如果線程在列塊中分配(例如dim3(1,256,1)),我看到執行時間總是更糟糕。這是什么原因?

首先,我要指出您的代碼僅適用於方形矩陣,通常您應該在代碼的所有三個位置使用A.ncols而不是A.nrows

性能差異是由於內存訪問。 你必須存儲在行主要格式的所有三個矩陣和代碼執行以下操作:每個線程訪問iy的排第Aix的列處B ,並計算它們的點積。 請注意,warp中的所有線程總是同時執行相同的指令,因此在代碼中的串行循環中,對於warp中的所有線程, i總是相同的。 在您的代碼中,塊形狀很重要,因為:

  • 如果塊大小是(256, 1, 1) ,則塊中的每個線程具有相同的iy ,但是ix不同。 讓我們看一下B的訪問模式:同一個warp中的所有線程總是訪問B的同一行,因為在B.value[i*B.nrows+ix]i是相同的而且ix不同,所以負載可以合並
  • 如果塊大小為(1, 256, 1) ,則情況會被轉置,因此您可能希望合並來自A的負載。 但事實並非如此,因為iy確定了行,並且兩個相鄰線程訪問的值被A.ncols偏移。

到接入圖案C是一樣的B ,但較不重要。 對於2D塊,情況介於兩個1D案例之間。

如果要進一步優化代碼,可以使用“ CUDA編程指南”中所示的共享內存。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM