在c++中简化复杂变量的OpenMP的优雅(和典型)解决方案
Elegant (and typical) workaround for OpenMP reduction on complex variable in C++?
我意识到缩减只适用于c++中的POD类型。如何实现复杂类型累加器的约简?
complex<double> x(0.0,0.0), y(1.0,1.0);
#pragma omp parallel for reduction(+:x)
for(int i=0; i<5; i++)
{
x += y;
}
(注意我可能遗漏了一些语法)。似乎一个显而易见的解决方案是将实分量和虚分量拆分为临时双精度,然后对它们进行累加。我想我追求的是优雅,而这似乎……不够漂亮。这是典型的做法吗?
在OpenMP中缺少用户定义缩减的情况下,典型的解决方案甚至比您建议的更难看。通常,在并行区域之前,人们创建一个包含(至少)与该区域中线程数量相等的元素的数组,使用omp_get_thread_num()
作为数组的索引分别为每个线程累积部分结果,并在并行区域之后的循环中对累积结果进行最终减少。
据我所知,OpenMP语言委员会正致力于在规范中添加用户定义的缩减,所以这个问题可能会在几年内最终解决。
对不起,OpenMP目前根本不支持。不幸的是,您需要以您已经描述的一种丑陋的方式进行并行约简。
然而,如果这种并行约简真的很频繁,我想做一个类似于TBB中的parallel_reduce
的构造函数。这种构造的实现相当直接。Cilk plus有一个更强大的reducer对象,但是我没有检查它是否支持非POD。
仅供参考,这种限制也可以在threadprivate
pragma中找到。我已经测试了vc++ 2008/2010和英特尔编译器(icc)。vc++不能支持具有构造函数或析构函数(或需要初始化函数调用的标量变量)的结构/类的threadprivate
,通过抛出错误:错误C3057,"'threadprivate'符号的动态初始化"。你也可以阅读这个MSDN链接。然而,icc对C3057的情况是可以接受的。您可以看到,至少有两种主要的实现是如此不同。
我想在非pod上支持并行缩减也会有类似的问题。为了支持并行缩减,每个并行段应该为缩减变量分配一个线程局部变量。因此,如果给定的缩减变量是非pod的,它们可能需要调用用户定义的构造函数。这就产生了我在C3057中提到的同样的问题。
- 运行同一解决方案的另一个项目的项目
- Project Euler问题4的错误解决方案
- 计算每个节点的树高,帮助我解释这个代码解决方案
- C++:Application.cpp中抛出了未解析的外部符号(解决方案在问题的末尾,供未来的读者参考)
- visual c++,如何获取解决方案目录中的代码
- 有没有办法在远程设备上打开和编辑visual Studio 2017解决方案
- C++Matching Brackets 2解决方案不起作用
- 在 ubuntu3 上C++ goto 定义有什么解决方案吗16.04?
- 在 leetcode 上提交解决方案时出现堆栈缓冲区溢出错误
- 我的固定时间步长与增量时间和插值的解决方案是错误的吗?
- 无法在问题解决方案中执行输出逻辑
- 最大的回文产品 - 程序未运行,编写解决方案但无法理解问题
- 从预序遍历构造 bst 的 c++ 和 python 解决方案之间的区别
- 在一个解决方案中针对第三方静态库 (Creo) 的不同版本(版本)进行构建
- 如何巧妙地编写两个函数——一个用于检查是否存在解决方案,另一个用于获取所有解决方案
- 使用 Git 处理 C++ Visual Studio 2019 解决方案的外部依赖项源代码管理的最佳方法是什么?
- N-queen问题:无法弄清楚为什么我的解决方案不起作用
- 从排序数组中删除重复项,具有不同代码方式的相同解决方案具有不同的输出
- 使用XOR查找O(n)-解决方案中的两个字符串是否为变位符
- 在c++中简化复杂变量的OpenMP的优雅(和典型)解决方案