簡體   English   中英

CUDA如何獲取網格、塊、線程大小和並行化非方陣計算

[英]CUDA how to get grid, block, thread size and parallalize non square matrix calculation

我是 CUDA 的新手,需要幫助理解一些事情。 我需要幫助並行化這兩個 for 循環。 具體如何設置dimBlock 和dimGrid 使其運行得更快。 我知道這看起來像 sdk 中的向量添加示例,但該示例僅適用於方陣,當我嘗試為 128 x 1024 矩陣修改該代碼時,它無法正常工作。

__global__ void mAdd(float* A, float* B, float* C)
{
    for(int i = 0; i < 128; i++)
    {
        for(int j = 0; j < 1024; j++)
        {
            C[i * 1024 + j] = A[i * 1024 + j] + B[i * 1024 + j];
        }
    }
}

這段代碼是一個更大循環的一部分,是代碼中最簡單的部分,所以我決定嘗試並行化 thia 並同時學習 CUDA。 我已經閱讀了指南,但仍然不明白如何獲得正確的編號。 網格/塊/線程去並有效地使用它們。

正如您所寫,該內核是完全串行的。 為執行它而啟動的每個線程都將執行相同的工作。

CUDA(以及 OpenCL 和其他類似的“單程序、多數據”類型的編程模型)背后的主要思想是您進行“數據並行”操作——因此必須多次執行相同的、很大程度上獨立的操作——並且編寫一個執行該操作的內核。 然后啟動大量(半)自治線程以跨輸入數據集執行該操作。

在您的數組加法示例中,數據並行操作是

C[k] = A[k] + B[k];

對於 0 到 128 * 1024 之間的所有 k。每個加法操作都是完全獨立的,沒有排序要求,因此可以由不同的線程執行。 要在 CUDA 中表達這一點,可以這樣編寫內核:

__global__ void mAdd(float* A, float* B, float* C, int n)
{
    int k = threadIdx.x + blockIdx.x * blockDim.x;

    if (k < n)
        C[k] = A[k] + B[k];
}

[免責聲明:在瀏覽器中編寫的代碼,未經測試,使用風險自負]

在這里,串行代碼的內循環和外循環被每個操作的一個 CUDA 線程替換,並且我在代碼中添加了一個限制檢查,以便在啟動的線程數超過所需操作的情況下,不會發生緩沖區溢出。 如果內核是這樣啟動的:

const int n = 128 * 1024;
int blocksize = 512; // value usually chosen by tuning and hardware constraints
int nblocks = n / blocksize; // value determine by block size and total work

madd<<<nblocks,blocksize>>>mAdd(A,B,C,n);

然后將 256 個塊(每個塊包含 512 個線程)啟動到 GPU 硬件上,以並行執行陣列加法操作。 請注意,如果輸入數據大小不能表示為塊大小的整數倍,則需要將塊數四舍五入以覆蓋完整的輸入數據集。

以上所有內容都是對 CUDA 范式的一個非常簡單的操作的極大簡化概述,但也許它為您提供了足夠的洞察力讓您繼續自己。 CUDA 這些天相當成熟,網上有很多好的免費教育材料,您可能可以用來進一步闡明我在這個答案中掩蓋的編程模型的許多方面。

暫無
暫無

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

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