2013-01-18 64 views
2

我正在嘗試爲OpenCL編寫互斥鎖。這個想法是每個單獨的工作項目都能夠自動進行的。目前,我認爲這個問題可能是因爲warp中的一個線程獲取鎖定時線程扭曲無法繼續。基本OpenCL互斥鎖實現(當前掛起)

我現在的簡單內核,用於求和數字。 「數字」是一組浮點數作爲輸入。 「sum」是結果的一個元素數組,「semaphore」是用於存放信號量的一個元素數組。我根據示例here嚴重依據它。

void acquire(__global int* semaphore) { 
    int occupied; 
    do { 
     occupied = atom_xchg(semaphore, 1); 
    } while (occupied>0); 
} 
void release(__global int* semaphore) { 
    atom_xchg(semaphore, 0); //the previous value, which is returned, is ignored 
} 
__kernel void test_kernel(__global float* numbers, __global float* sum, __global int* semaphore) { 
    int i = get_global_id(0); 
    acquire(semaphore); 
    *sum += numbers[i]; 
    release(semaphore); 
} 

我打電話有效內核喜歡:

int numof_dimensions = 1; 
size_t offset_global[1] = {0}; 
size_t size_global[1] = {4000}; //the length of the numbers array 
size_t* size_local = NULL; 
clEnqueueNDRangeKernel(command_queue, kernel, numof_dimensions,offset_global,size_global,size_local, 0,NULL, NULL); 

如上所述,運行時,顯卡掛起,司機重新啓動。我怎樣才能解決它,讓它不?

回答

-1

回想起來,這個問題的答案看起來很明顯,但除非你想到這個問題。

基本上,GPU對理想本地組大小(線程扭曲的大小)的預測大於1,所以線程扭曲鎖定。要修復它,你只需要指定它爲1(即「size_t size_local [1] = {1};」)。這樣做會產生正確的結果。

2

由於GPU執行模式,即使在分支中,「處理器」上的所有線程都共享指令指針,因此您所要做的不可能。這裏有一篇文章詳細解釋了這個問題:http://vansa.ic.cz/author/admin/

順便說一句,您發現的示例代碼有完全相同的問題,將永遠不會工作。

+0

我知道GPU的工作方式。但是,使用一個本地大小(如示例代碼所做的那樣)完美地工作。我將此作爲證據,證明這樣做會爲每個線程扭曲一個線程(或者說,只保存一個線程的執行)。線程扭曲無法鎖定,因爲每個線程中只有一個線程在運行!引用的鏈接給出了另一個有趣的解決方法,但我認爲它最終以不太便攜的方式做同樣的事情。 – imallett