我有一个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之间变化,结果随着运行而变化 有人能告诉我我错过了什么,或者如何正确地做到这一点?
答案 0 :(得分:2)
您无法使用opencl在不同的工作组之间进行同步。 CLK_GLOBAL_MEM_FENCE无法正常工作。它只保证维护内存操作的顺序(由工作组访问)。请参阅OCL 1.2 spec中的“6.12.8同步功能”部分。
我会通过为每个工作组使用不同的全局内存块来解决您的问题。您将数据写入全局,并且您的内核已完成。然后,如果要将数据减少到单个块,可以使另一个内核从全局读取数据,并将其与其他结果块合并。您可以根据需要执行多个合并层,但最终合并必须由单个工作组完成。
搜索gpu / opencl减少算法。这是一个体面的开始。 Case Study: Simple Reductions