OpenMP 4.0并行for循环使用std::map的reduction写法报错求解
OpenMP 4.0 并行化std::map计数循环的自定义reduction正确写法
你遇到的no viable conversion from 'int' to 'std::map<int, int>'编译错误,来自自定义reduction声明的两处写法问题:
initializer子句错误地将int类型的0赋值给std::map<int,int>类型的线程私有变量,触发类型不匹配- 直接使用
omp_out += omp_in作为合并逻辑不成立,C++标准库并未为std::map重载+=运算符,无法直接完成两个map的计数累加
自定义map的加法归约需要明确两个核心逻辑:
- 每个线程启动时,私有map副本初始化为空map实例
- 归约阶段,遍历待合并map的所有键值对,将对应键的计数累加到目标map中
正确可运行的代码写法如下:
int n = 5000; std::map<int, int> histogram; // 适配std::map<int,int>的加法归约声明 #pragma omp declare reduction(+ : std::map<int, int> : \ // 归并逻辑:遍历输入map的所有键值对,累加到输出map对应键 for (const auto& kv : omp_in) { \ omp_out[kv.first] += kv.second; \ } \ ) \ // 初始化逻辑:每个线程的私有副本初始化为空map initializer(omp_priv = std::map<int, int>()) // 并行循环制导指令 #pragma omp parallel for reduction(+ : histogram) for (int i = 1; i < n; i++) { int nbin; // 原有nbin计算逻辑 // ... ++histogram[nbin]; }
注意事项
- 该实现不存在数据竞争:并行阶段每个线程仅操作自己的私有map副本,循环结束后OpenMP自动调用归并逻辑,将所有线程的计数汇总到全局
histogram变量中 - 编译时需要确认开启OpenMP 4.0及以上版本支持:GCC添加
-fopenmp编译参数,Clang添加-fopenmp=libomp参数,MSVC在编译选项中开启OpenMP支持即可。
内容的提问来源于stack exchange,提问作者ralf_7
相关产品推荐
相关产品推荐

