OpenMP嵌套循环采用task并行时计数器输出结果不正确问题求助
OpenMP task嵌套循环计数错误修复
错误原因
- 共享变量
pixels_inside无同步保护:多任务并行执行pixels_inside++操作时,自增属于读-改-写三步操作,无同步的并发写入会导致计数结果丢失。你之前使用parallel for时的reduction子句已经处理了求和的同步逻辑,task版本未做对应处理是核心问题。 - 补充说明:OpenMP默认会在并行区域结束前等待所有生成的task执行完成,不需要额外加同步指令等待任务结束。
修复方案
方案1:原子操作保护写入(写法简单,适合小计算量场景)
直接对自增操作加原子更新指令,避免并发写入冲突:
#include<iostream> #include<omp.h> using namespace std; int main(){ int total_steps = 10000; int i,j; int pixels_inside=0; omp_set_num_threads(4); #pragma omp parallel #pragma omp single private(i) for(i = 0; i < total_steps; i++){ #pragma omp task private(j) for(j = 0; j < total_steps; j++){ // 原子保护自增操作 #pragma omp atomic update pixels_inside++; } } cout<<"Total pixel = "<<pixels_inside<<endl; return 0; }
方案2:任务规约(性能更高,适合大计算量场景)
使用taskloop+reduction的写法,每个任务维护局部计数,最后合并结果,避免频繁原子操作的开销:
#include<iostream> #include<omp.h> using namespace std; int main(){ int total_steps = 10000; int pixels_inside=0; omp_set_num_threads(4); #pragma omp parallel #pragma omp single { // taskloop自动为循环生成任务,reduction自动合并所有任务的计数结果 #pragma omp taskloop reduction(+:pixels_inside) for(int i = 0; i < total_steps; i++){ for(int j = 0; j < total_steps; j++){ pixels_inside++; } } } cout<<"Total pixel = "<<pixels_inside<<endl; return 0; }
内容的提问来源于stack exchange,提问作者Dev. R
相关产品推荐
相关产品推荐

