[英]CUDA Thread IDs
我是CUDA編程的新手,但遇到以下問題。
如果我使用以下代碼執行矩陣乘法,由於CUDA使用笛卡爾索引進行線程索引,而C / C ++使用行主要索引進行矩陣,這會不會影響計算的准確性?
__global__ void gpuMM(float *A, float *B, float *C, int N)
{
// Matrix multiplication for NxN matrices C=A*B
// Each thread computes a single element of C
int col = blockIdx.y*blockDim.y + threadIdx.y;
int row = blockIdx.x*blockDim.x + threadIdx.x;
float sum = 0.f;
for (int n = 0; n < N; ++n)
sum += A[row*N+n]*B[n*N+col];
C[row*N+col] = sum;
}
CUDA並不暗示任何內存存儲結構。 您可以說CUDA C對於矩陣存儲來說是行優先的,但這是由於C而不是CUDA。 (CUDA Fortran將是主要列。)線程索引尺寸是任意的。 它們並不表示內存中的數據存儲順序。
當然,在編寫代碼時會涉及到內存中數據存儲順序的含義。 從正確性的角度來看,我們是否基於x線程尺寸或y線程尺寸分配行索引都沒有關系。 您可以使用兩種方法(基於x的行或基於y的行)為此矩陣乘法示例編寫正確的代碼。
但是,從合並的角度來看,我們通常希望相鄰執行線程讀取或寫入內存中的相鄰單元。 相鄰線程(用於執行)通常按x分組。 因此,這是更可取的(對於您的內核代碼):
int row = blockIdx.y*blockDim.y + threadIdx.y;
int col = blockIdx.x*blockDim.x + threadIdx.x;
因為它將允許B[]
的讀取和C[]
的寫入合並。
這很容易向自己證明。 兩種方法都嘗試一下,並測量內核的執行時間。 兩種方法的結果都是正確的(與使用基於宿主的基質相乘產生的結果相匹配),但是一種配方的運行速度明顯快於另一種。
這一點特別容易嘗試,因為您的內核代碼暗含平方矩陣。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.