2012-11-27 91 views
0

創建線程的網格我寫了針對OpenCL內核,我初始化一個三維陣列中的所有元素 - >我* I * I + J *∫*∫。我現在在創建一個線程網格來執行元素初始化(併發)時遇到了問題。我知道我現在使用的代碼只使用3個線程,我該如何擴展?OpenCL中

請幫忙。我是OpenCL的新手,所以任何建議或解釋可能都很方便。謝謝!

這是代碼:

_kernel void initialize (
int X; 
int Y; 
int Z; 
_global float*A) { 

// Get global position in X direction 
int dirX = get_global_id(0); 
// Get global position in Y direction 
int dirY = get_global_id(1); 
// Get global position in Z direction 
int dirZ = get_global_id(2); 

int A[2000][100][4]; 
int i,j,k; 
for (i=0;i<2000;i++) 
{ 
    for (j=0;j<100;j++) 
    { 
     for (k=0;k<4;k++) 
     { 
      A[dirX*X+i][dirY*Y+j][dirZ*Z+k] = i*i*i + j*j*j; 
     } 
    } 
} 
} 
+0

它看起來像這樣的代碼通過甲在作爲__global浮子*,然後redeclares它作爲一個int數組,這是固有的私人。那是故意的嗎? – boiler96

+0

嗨,除了隱藏鍋爐96突出顯示的'A'變量,爲什麼你說你只使用3個線程?你的工作組大小有3個維度(X,Y和Z),所以我懷疑你在調用代碼中創建了多於3個線程(工作項目)。你想要什麼尺寸的最終輸出數組 - 2000x100x4或這些尺寸的倍數? –

+0

@ boiler96我認爲這是我犯的一個錯誤,它應該是一個數組。你能幫助解決這個問題嗎? –

回答

0
  • 創建緩衝區來存儲你的輸出 'A' 在調用(主機)的代碼。它作爲一個指針傳遞給你的內核,這在上面的函數定義中是正確的。但是,您不需要在內核函數中再次聲明它,因此請刪除行int A[2000][100][4];

  • 可以大大簡化代碼。使用3D全局ID來指示3D指數在數組中的每一個工作項,你可以改變環路如下(假設對於給定的i和j,向Z的所有元素應該具有相同的值):

    __kernel void initialize (__global float* A) { 
        // cast required so that kernel compiler knows the array dimensions 
        __global float (*a)[2000][100][4] = A; 
    
        // Get global position in X direction 
        int i = get_global_id(0); 
        // Get global position in Y direction 
        int j = get_global_id(1); 
        // Get global position in Z direction 
        int k = get_global_id(2); 
    
        (*a)[i][j][k] = i*i*i + j*j*j; 
    } 
    

在您的調用代碼中,您將創建一個全局工作大小爲2000x100x4的內核。

  • 實際上,這是一個很多的工作項目安排,所以你可能會從全球(一維)2000年工作的大小和內核內部循環,例如,獲得更好的性能:

    __kernel void initialize (__global float* A) { 
        // cast required so that kernel compiler knows the array dimensions 
        __global float (*a)[2000][100][4] = A; 
    
        // Get global position in X direction 
        int i = get_global_id(0); 
    
        for (j=0;j<100;j++) { 
        for (k=0;k<4;k++) { 
         (*a)[i][j][k] = i*i*i + j*j*j; 
        } 
        } 
    } 
    
+1

只是一個相關的問題。如果「A」不是定義的矩陣,那麼編譯器如何知道每個維度的大小?我想知道A [i * 100 * 4 + j * 4 + k]是否是訪問矩陣的正確方法。 – DarkZeros

+1

前兩個項目符號是對這個問題的一個很好的回答,但我不同意你的最後一個項目符號。最好儘可能簡單地編寫代碼,讓工作組大小不定,然後讓OpenCL SDK處理準備優化的代碼。除非您正在考慮使用特定的硬件,並且已經將此代碼標識爲低效,否則我認爲不需要像這樣修改它。 – Oak

+0

@DarkZeros,+1好點,我已經添加了一個演員來迎合這個答案。另一種方法是按照您的建議使用一維數組,或許將尺寸作爲參數傳遞給內核。 –