簡體   English   中英

在Cuda中將3D陣列展平為1D

[英]Flattening a 3D array to 1D in cuda

我嘗試在cuda中實現以下代碼,但是在cuda中將3D數組展平為1D時遇到問題

C ++代碼

for(int i=0; i<w; i++)
  for(int j=0; j<h; j++)
    for(int k=0; k<d; k++)
     arr[h*w*i+ w*j+ k] = (h*w*i+ w*j+ k)*2;

這是我到目前為止在Cuda擁有的

  int w = h = d;
  int N = 64;

 __global__ void getIndex(float* A)
{
  int i = blockIdx.x;
  int j = blockIdx.y;
  int k = blockIdx.z;
  A[h*w*i+ w*j+ k] = h*w*i+ w*j+ k;
}


int main(int argc, char **argv)
 {

    float *d_A;
    cudaMalloc((void **)&d_A, w * h * d * sizeof(float) );
    getIndex <<<N,1>>> (d_A);
  }

但是我沒有得到期望的結果,我不知道如何獲得正確的i,jk索引

考慮尺寸的3D問題w X h X d (這可能是一個簡單的數組,必須像在您的問題或任何其他易於並行化的3D問題中一樣進行設置。)我將使用您的簡單設置任務進行演示。

使用CUDA內核處理此問題的最簡單方法是為每個數組條目啟動一個線程,即w*h*d線程。 這個答案討論了為什么每個元素一個線程可能並不總是最好的解決方案。

現在讓我們看一下下面的代碼行

dim3 numThreads(w,h,d);
getIndex <<<1, numThreads>>> (d_A, w, h, d);

在這里,我們正在啟動一個總共有w*h*d線程的內核。 內核可以實現為

__global__ void getIndex(float* A, int w, int h, int d) // we actually do not need w
{
    int i = threadIdx.x;
    int j = threadIdx.y;
    int k = threadIdx.z;
    A[h*d*i+ d*j+ k] = h*d*i+ d*j+ k;
}

但是該內核和內核調用存在一個問題:每個線程塊的線程數是有限的(“特定方向上的線程數”也有界= z方向通常是最大界)。 因為我們只調用一個線程塊,所以我們的問題大小不能超過這些特定限制(例如w*h*d <= 1024 )。

這就是線程塊的用途。 實際上,您可以根據需要啟動具有多個線程的內核。 (這是不正確的,但是線程塊最大數量的限制不太可能用盡。)

以這種方式調用內核:

dim3 numBlocks(w/8,h/8,d/8);
dim3 numThreads(8,8,8);
getIndex <<<numBlocks, numThreads>>> (d_A, w, h, d);

將為w/8 * h/8 * d/8線程塊啟動內核,而每個塊包含8*8*8線程。 因此總共將調用w*h*d線程。 現在我們必須相應地調整內核:

__global__ void getIndex(float* A, int w, int h, int d) // we actually do not need w
{
    int bx = blockIdx.x;
    int by = blockIdx.y;
    int bz = blockIdx.z;
    int tx = threadIdx.x;
    int ty = threadIdx.y;
    int tz = threadIdx.z;
    A[h*d*(8*bx + tx)+ d*(8*by + ty)+ (8*bz + tz)] = h*d*(8*bx + tx)+ d*(8*by + ty)+ (8*bz + tz);
}

注意:

  • 您可以使用blockDim.x而不是固定大小8gridDim.x編寫更通用的內核,以通過gridDim.x*blockDim.x計算w 其他兩個維度也同樣處理。
  • 在建議的示例中,所有三個維度whd必須為8的倍數。您還可以泛化內核以允許每個維度。 (然后,您必須將所有三個維度解析到內核,以檢查計算出的位置是否仍在問題范圍之內。)
  • 如前所述,在每個線程中編輯數組的一個以上條目可能更為有效。 調用內核時必須再次考慮這一點。 包裝函數可以使用問題大小和數據,並使用正確的塊和線程配置調用內核。

暫無
暫無

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

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