2012-11-06 35 views
0

我包括我懷疑是不正確這裏的主人計劃的主要部分:有人可以解釋這個OpenCL程序有什麼問題嗎?

http://pastebin.com/qVkv9E11

我不是指針,偉大又和想我可能已經分配的一些變量是錯誤的。

這裏是內核程序,它應該給什麼我的程序試圖做一個想法:

const char *KernelSource =   "\n" 
"__kernel void sumElements(   \n" 
" __global float* input,   \n" 
" __global float output,   \n" 
" __global int N)     \n" 
"{         \n" 
" int i = get_global_id(0);   \n" 
" if(i < N)       \n" 
"  output += input[i];   \n" 
"}         \n" 
"\n"; 

也許正是這個原因導致了錯誤,因爲我從來沒有嘗試過SIMT如上面寫着一個變量。是否有可能做這樣的事情?我需要得到數組中所有元素的總和。

回答

5

如果您試圖回讀輸出的值,那麼您還需要將其聲明爲指針。現在,輸出的值作爲內核參數被複制,但是在內核結束後,您對其做出的任何更改都將被忽略。因此,將__global float output更改爲__global float* output。然後,在你的內核變化:

if(i < N) 
    output += input[i]; 

if(i < N) 
    *output += input[i]; 

您可能需要改變你分配好自己的緩衝區來此上班的路上,但它是一個很長的時間,因爲我已經做了這在OpenCL中,我現在發現的文檔並沒有在你的緩衝區中顯示任何明顯的錯誤。

這裏有個警告:另外是不是原子操作。通過這種設置,總會發生的是,您將有兩個或更多線程讀取* output的值,然後嘗試在不同階段將* output + 1寫回。因此,*輸出將具有比它應該小的值。

爲了解決這個問題,你將需要使用OpenCL的atomic operations.

+3

只需添加到Telgin的答案,各個元素相加所示(使用原子操作雖然在技術上可以實現的)是非常低效的。您可能需要考慮減少問題:例如,如果您的輸入具有N個元素,則創建I個工作項目,每個項目負責彙總N/I元素,然後(i)輸出部分彙總數組,然後累積回(ii)使用OpenCL內存屏障,並在輸出單個值之前讓一個工作項在設備上累積部分總和。 –

+0

非常好!正如您所描述的,將變量更改爲指針。我認爲它具有*成功的變量類型使它成爲一個指針並且在變量dereferences之前呢? 你對原子操作是正確的。現在只返回1。我會做一些閱讀。 – Chucky

+1

@Chucky是的,沒錯。在變量聲明中使用*會使其成爲一個指針,然後通過訪問指針處的值來取消引用它。另外,詹姆斯比爾比是正確的,因爲這是非常低效的,一旦你確定自己的工作是按照預期工作的,那麼你應該仔細閱讀減少計劃以使其更快。 – Telgin

相關問題