2012-10-03 51 views
0

當我嘗試在內核中查找有關原子操作的更多細節時,發現有些奇怪的東西。據我所知,當在一個數字上使用原子操作時,所有線程的所有這類操作都將被序列化以啓動此數字以保持完整性。以下是我的一個內核代碼:OpenCL內核中的原子操作

if(atomic_cmpxchg(&A[ptr],0,-1) == -1) 
     ptr = A[ptr + 3]; 

    //To delay 
    uint k = 1000000; 
    while(k--); 

    A[ptr + 3] = newValue; 

對於上面的代碼,假設只有兩個線程T1和T2。據我所知,T1和T2都會執行代碼片段,但是當他們嘗試執行atomic_cmpxchg操作時,T2必須等待T1完成(假設T1先運行)。按照我的設計,當T1讀取A [ptr]時,A [ptr]的舊值爲0,因此它將以原子方式更改爲-1。之後,由於對於T1,條件不滿足,所以T1將直接進入延遲代碼並被延遲。現在是T2工作於A [ptr]的時候了,因爲現在A [ptr]已經被設置爲-1,所以T2的條件滿足了,所以T2將運行到「ptr = A [ptr + 3];」 。但是我的問題是:因爲在T2完成條件判斷之後,它會執行「ptr = A [ptr + 3];」立即,但T1遇到延遲,所以A [ptr + 3]的值還沒有被T1更新過(因爲k很大,延遲會很長)。因此,T2將不讀取A [ptr + 3]的最新值,該值應該是新值。但是我的實驗表明,無論我設置了多大的值,結果總是正確的,即無論T1遇到多長時間,T2始終可以讀取正確的值(新值)。任何人都可以幫助看看這種情況?非常感謝。

回答

2
  1. 編譯器可能足夠聰明地發現你的「延遲」循環沒有副作用並完全優化它。

  2. 在GPU上,來自同一工作組的OpenCL工作項通常在lock-step(至少在某種程度上取決於確切的硬件)下運行。這意味着兩個線程同時執行相同的指令。他們基本上共享一個指令指針。如果有不同的控制流程,每個線程都會記錄它是否當前處於活動狀態,並且只有在執行當前指令時才記錄。原子操作仍然是序列化的。