2012-09-12 94 views
0

我在這裏遇到問題。我啓動兩個內核,檢查是否有某個值是預期值(memcpy到主機),如果是我停止,如果不是,我再次啓動兩個內核。CUDA內核和內存訪問(一個內核不能完全執行,下一個不會啓動)

第一內核:

__global__ void aco_step(const KPDeviceData* data) 
{ 
int obj = threadIdx.x; 
int ant = blockIdx.x; 
int id = threadIdx.x + blockIdx.x * blockDim.x; 

*(data->added) = 1; 

while(*(data->added) == 1) 
{ 
    *(data->added) = 0; 

    //check if obj fits 
    int fits = (data->obj_weights[obj] + data->weight[ant] <= data->max_weight); 
    fits = fits * !(getElement(data->selections, data->selections_pitch, ant, obj)); 

    if(obj == 0) 
     printf("ant %d going..\n", ant); 
    __syncthreads(); 

... 

的代碼在此之後繼續。但是printf永遠不會被打印出來,只是出於調試目的,syncthreads就在那裏。

「增加」變量是共享的,但由於共享內存是PITA,並且通常會在代碼中拋出錯誤,我現在只是將其刪除。這個「添加」變量並不是最聰明的事情,但它比替代方法更快,它會檢查數組中的任何變量是否是主機上的某個值,並決定是否繼續迭代。

的getElement,根本矩陣存儲器計算與俯仰訪問正確的位置,並返回該元件有:

int* el = (int*) ((char*)mat + row * pitch) + col; 
return *el; 

的obj_weights陣列具有合適的尺寸,N *的sizeof(int)的。重量數組也是如此,螞蟻* sizeof(float)。所以他們不是越界。

內核之後的內核在開始時有一個printf權限,它不會被打印出來,並且在printf之後,它會在設備內存上設置一個變量,並在內核完成後將該內存複製到CPU ,而當我在CPU代碼中打印它時,這不是正確的值。所以我認爲這個內核做了一些非法的事情,第二個甚至沒有啓動。

我正在測試一些實例,當我啓動8個塊和512個線程時,它運行正常。 32個塊,512個線程,確定。但是8個塊和1024個線程,發生這種情況,內核不能工作,既沒有32塊也沒有1024線程。

我做錯了什麼?內存訪問?我是否啓動了太多線程?

編輯:嘗試刪除「添加」變量和while循環,所以它應該只執行一次。仍然沒有工作,沒有打印,即使printf正好在三個首行後面,下一個內核也不會打印任何東西。

編輯:另一件事,我使用的是GTX 570,因此根據http://en.wikipedia.org/wiki/CUDA,「每塊最大線程數」爲1024。也許我會堅持512最大或檢查我可以把這個價值多高。

回答

2

__syncthreads()只有條件代碼中的條件在塊的所有線程上的計算結果相同才被允許。

在你的情況下,這種情況會遇到競爭條件,並且是不確定的,所以它很可能評估不同線程的不同結果。

printf()輸出僅在內核成功完成後顯示。在這種情況下,它不是由於上面提到的問題,所以輸出從不出現。您可以通過測試所有CUDA函數調用錯誤的返回碼來計算出這一點。

+0

好吧,我得到了syncthreads點,完全忘了它。但是關於內存寫入,如果多個線程向相同的地址寫入相同的值,則值將被更新,未知的是它將被更新多少次。採取從這裏:http://stackoverflow.com/questions/5953955/concurrent-writes-in-the-same-global-memory-location – hfingler

+0

Upvoted,因爲我不知道內核啓動返回的錯誤,所以我很接近發現問題。這裏有錯誤捕獲代碼:http://code.google.com/p/stanford-cs193g-sp2010/wiki/TutorialWhenSomethingGoesWrong – hfingler

+0

我不完全確定*(數據 - >添加)測試是做什麼的。但是爲了至少消除競爭條件,在while()之前插入__syncthreads()。由於__syncthreads()每塊同步,這也需要將標誌移回共享內存(不要害怕它 - 如果編程正確,共享內存沒有問題)。 – tera