使用OpenMP并行化此递归的最佳方法
Best way to parallelize this recursion using OpenMP
我具有以下递归功能(注意:它被剥离了所有不重要的细节)
int recursion(...) {
int minimum = INFINITY;
for(int i=0; i<C; i++) {
int foo = recursion(...);
if (foo < minimum) {
minimum = foo;
}
}
return minimum;
}
注2:它是有限的,但在这个简化的示例中不是,所以请忽略它。这个问题的重点是如何正确解决此问题。
我正在考虑使用任务,但是我不确定如何正确使用它 - 如何将内部周期置换。
编辑1:递归树不能很好地平衡。它与动态编程方法一起使用,因此随着时间的流逝,从以前的通过中重新使用了许多值。这让我非常担心,我认为这将是一个很大的瓶颈。
c在20。
左右。最好的度量是最快的:)
它将在2x Xeon上运行,因此可以使用大量的HW功率。
我将在vector
中收集结果,并计算最小值外部。您也可以在任务中执行受保护的(关键/锁定)的最小计算。
,如果您在递归中太深,则避免在最低限度的情况下产卵任务/分配内存,在递归中,开销/工作比率太差了。最强的解决方案是创建两个独立的(并行/串行)递归函数。这样,一旦切换到串行功能,您就会有零运行时的开销 - 而不是每次在统一功能中检查递归深度。
int recursion(...) {
#pragma omp parallel
#pragma omp single
return recursion_par(..., 0);
}
int recursion_ser(...) {
int minimum = INFINITY;
for(int i=0; i<C; i++) {
int foo = recursion_ser(...);
if (foo < minimum) {
minimum = foo;
}
}
return minimum;
}
int recursion_par(..., int depth) {
std::vector<int> foos(C);
for(int i=0; i<C; i++) {
#pragma omp task
{
if (depth < threshhold) {
foos[i] = recursion_par(..., depth + 1);
} else {
foos[i] = recursion_ser(...);
}
}
}
#pragma omp taskwait
return *std::min_element(std::begin(foos), std::end(foos));
}
显然,您不得在不重要的细节中使用全球/共享状态做任何令人讨厌的事情。
相关文章:
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- 在C++中向零方向近似的最佳方法
- 使用不同的CRT将新的C++代码与旧的(二进制)组件隔离开来的最佳方法是什么
- 检测win32服务创建和删除的最佳方法
- 在C++中样板"冷/never_inline"错误处理技术的最佳方法是什么?
- 在 c++ 中对类中的 c 字符串动态数组进行排序的最佳方法是什么?
- 将线程中的数据存储到全局容器的最佳方法?
- 将一系列整数放入类的最佳方法是什么?
- 在派生类中使用基类的私有成员变量的最佳方法
- 在 C++ 中将非指定类型作为参数传递的最佳方法?
- Qt - QVector 和模型视图 - 从列表视图获取自定义类的最佳方法是什么?
- 使用 Git 处理 C++ Visual Studio 2019 解决方案的外部依赖项源代码管理的最佳方法是什么?
- 比较两个节点坐标的最佳方法是什么?
- 在nodejs中使用本机代码的最佳方法是什么?
- 将 pybind11 绑定标记为已弃用的最佳方法
- C++:将向量传递到构造函数以创建成员变量的最佳方法?
- C++中变量混叠的最佳方法
- 读取大文件(>2GB)(文本文件包含以太网数据)并通过不同参数随机访问数据的最佳方法是什么?