簡體   English   中英

CUDA線程ID

[英]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.

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