OpenMP递归任务
OpenMP recursive tasks
考虑以下计算斐波那契数的程序。
它使用OpenMP任务来并行化。
#include <iostream>
#include <omp.h>
using namespace std;
int fib(int n)
{
if(n == 0 || n == 1)
return n;
int res, a, b;
#pragma omp parallel
{
#pragma omp single
{
#pragma omp task shared(a)
a = fib(n-1);
#pragma omp task shared(b)
b = fib(n-2);
#pragma omp taskwait
res = a+b;
}
}
return res;
}
int main()
{
cout << fib(40);
}
我使用gcc 4.8.2版本和Fedora 20。
在编译上述程序时,使用g++ -fopenmp name_of_program.cpp -Wall然后运行它,我发现在查看htop时只有两个(有时是3个)线程在运行。我运行这个程序的机器有8个逻辑cpu。我的问题是,我需要做些什么来卸载工作到8个线程。我尝试导出OMP_NESTED=TRUE,但这会导致在运行时出现以下错误计划:
libgome:线程创建失败:资源暂时不可用
我的程序的重点不是有效地计算斐波那契数,而是在OpenMP中使用任务或类似的东西
使用OMP_NESTED=FALSE,一组线程被分配到顶级并行区域,并且在每个嵌套层上没有额外的线程,因此最多有两个线程将做有用的工作。
使用OMP_NESTED=TRUE,在每个级别分配一组线程。在您的系统上有8个逻辑cpu,因此团队规模可能为8。该团队包括一个来自该地区以外的线程,因此只启动了7个新线程。fib(n)的递归树大约有fib(n)个节点。(fib的一个很好的自引用属性!)因此,代码可能会创建7*fib(n)个线程,这会很快耗尽资源。
解决方法是在整个任务树周围使用单个并行区域。将omp parallel
和omp single
逻辑移到main,在fib之外。这样单线程团队就可以处理整个任务树。
一般的要点是要区分潜在的平行和实际的平行。任务指令指定潜在的并行性,在执行过程中可能会使用,也可能不会使用。omp parallel
(用于所有实际目的)指定实际并行度。通常您希望实际的并行度与可用的硬件相匹配,这样就不会使机器陷入瘫痪,但是潜在的并行度要大得多,这样运行时就可以平衡负载。
- 通过递归进行因子分解
- 递归函数计算序列中的平方和(并输出过程)
- 使用递归的数组的最小值.这是怎么回事
- 递归列出所有目录中的C++与Python与Ruby的性能
- 递归计数给定目录的文件和所有目录
- 如何在BST的这个简单递归实现中消除警告
- C++:正在检查LinkedList中的回文-递归方法-错误
- 递归模板化函数不能分配给具有常量限定类型"const tt &"的变量"state"
- 递归无序映射
- TSP递归解的迭代形式
- 如何在Elixir中调用递归函数并行
- 返回递归调用和仅递归调用的区别
- 数组元素打印的递归方法
- 使用递归时获取变量的奇怪值
- 递归求和任务的错误答案
- 将目标数字拆分为一系列数字(递归任务)
- OpenMP:即使在深度极限的情况下,递归任务也比顺序慢
- 多线程递归任务同步
- 在TBB中使用递归、基于任务的并行编程获得不同的输出
- OpenMP递归任务