2012-09-21 57 views
1

我有一個OpenCL內核,其中每個工作組都在本地內存中生成一個結果向量。然後,我需要將所有這些結果彙總到全局內存中,以便以後檢索到主機。
爲了測試這一點,我創建了下面的內核代碼:如何在OpenCL中同步本地到全局內存的結果

//1st thread in each workgroup initializes local buffer 
if(get_local_id(0) == 0){ 
    for(i=0; i<HYD_DIM; i++){ 
     pressure_Local[i] = (float2){1.0f, 0.0f}; 
    } 
} 

//wait for all workgroups to finish accessing any memory 
barrier(CLK_GLOBAL_MEM_FENCE | CLK_LOCAL_MEM_FENCE); 

/// sum all the results into global storage 
for(i=0; i<get_num_groups(0); i++){ 

    //1st thread in each workgroup writes the group's local buffer to global memory 
    if(i == get_group_id(0) && get_local_id(0) == 0){ 
     for(j=0; j<HYD_DIM; j++){ 
      pressure_Global[j] += pressure_Local[j]; 
      // barrier(CLK_GLOBAL_MEM_FENCE); 
     } 
    } 

    //flush global memory buffers: 
    barrier(CLK_GLOBAL_MEM_FENCE); 
} 

在本質上,我期待在全局存儲器中的向量的所有元素爲(在我的情況128)等於工作組的數量。事實上,他們通常在60到70之間變化,並且結果從跑步變爲跑步。
有人能告訴我這是什麼,我失蹤,或如何正確地做到這一點?

回答

2

您不能使用opencl在不同的工作組之間進行同步。 CLK_GLOBAL_MEM_FENCE不會以這種方式工作。它只保證內存操作的順序(由工作組訪問)將保持不變。請參閱OCL 1.2 spec中的「6.12.8同步功能」一節。

我會通過爲每個工作組使用不同的全局內存塊來解決您的問題。您將數據寫入全局,並且您的內核已完成。然後,如果要將數據減少爲單個塊,則可以使另一個內核從全局讀取數據,並將其與其他結果塊合併。您可以根據需要進行多層合併,但最終合併必須由單個工作組完成。

搜索gpu/opencl簡化算法。這是一個體面的開始。 Case Study: Simple Reductions