c++ - 在不能应用 omp atomic/reduction 的情况下,我们可以使用 omp critical 来提高效率吗?
问题描述
我在 C++ 中面临一个问题。
假设我们有vector<SomeClass> v
并且我们想要添加v
使用多线程的所有元素。(的大小v
是N
。)我们有一个重载的+=
运算符 inSomeClass
但这不是原子兼容的。
SomeClass sum; // init by "zero" but not exactly a single (int)
#pragma omp parallel for
for (int i=0; i<N; ++i) {
#pragma omp critical
{
sum += v[i];
}
}
我的实验表明,这段代码的运行时间与单线程的类似。我认为这是由于critcial
一次只允许一个线程评估添加的部分。(我无法利用多线程)。替代方法是使用atomic
or ( reduction
),但它们不可用,因为+=
不适用于原子变量。
在这种情况下,我们能做什么?我应该在这里退出使用多线程吗?非常感谢。
解决方案
你需要做减法。reduction(op:var)
如果openMP的标准指令不支持该类,您可以手动添加它。
每个线程将向量值相加到一个私有累加器中。然后,将私有累加器相加成一个全局累加器(对于整个循环,每个线程只需执行一次,而不是在每次迭代时)
SomeClass sum; // init by "zero" but not exactly a single (int)
#pragma omp parallel
{
SomeClass mySum=0; //local accumulator, init with 0 or whatever the "zero" is for that class
#pragma omp for
for (int i=0; i<N; ++i) mySum += v[i];
#pragma omp critical
sum += mySum; //The critical section is entered only once
}
推荐阅读
- stringbuilder - Apache Common 的 StrBuilder 和 Java 的 StringBuilder 有什么区别?
- model-view-controller - 如何在 KendoUI 调度程序上制作年度视图?
- angular - 如何使用primeng表格单元格添加带有无变形文本的图标结尾
- android - 从谷歌商店获取应用版本和新功能
- c# - DataTable 到 GridView 没有显示结果表
- numpy - Optimal way to find index of first occurrence of subarray in each frame of batch data without for loop
- vhdl - 将输出连接到 DAC - VHDL
- c# - 如何在 c# 中获取@rErr / 输出参数值?
- mysql - 如何在 SSMS 中加入名为“身份”的列?
- angular - 将数据从子组件传递到父组件时出错