OpenMP:即使在深度极限的情况下,递归任务也比顺序慢
openmp: recursive task slower than sequential even with depth limit
我有一棵非常大的二进制树,我想在上进行某些昂贵的计算。我想使用openMP及其任务布拉格马并平行这些方法。
作为测试,我已经平行了freeTree
功能,并且创建了一个大型示例测试树。为了防止产卵许多任务,我将创建任务的创建限制在树的前两个层面上。因此,有效地创建了4个任务。
以下是最小的工作示例:
#include <chrono>
#include <iostream>
class Node {
public:
int data;
Node* l;
Node* r;
Node(Node* left, Node* right) : l(left), r(right) {}
};
Node* createRandomTree(int depth) {
if (depth == 0)
return new Node(NULL, NULL);
return new Node(createRandomTree(depth - 1), createRandomTree(depth - 1));
}
void freeTree(Node* tree) {
if (tree == NULL) return;
freeTree(tree->l);
freeTree(tree->r);
delete tree;
}
void freeTreePar(Node* tree, int n = 0) {
if (tree == NULL) return;
Node *l = tree->l, *r = tree->r;
if (n < 2) {
#pragma omp task
freeTreePar(l, n + 1);
#pragma omp task
freeTreePar(r, n + 1);
} else {
freeTree(tree->l);
freeTree(tree->r);
}
// taskwait is not necessary
delete tree;
}
int main(int argc, char const *argv[])
{
std::chrono::time_point<std::chrono::system_clock> start, end;
Node* tree = createRandomTree(22);
start = std::chrono::system_clock::now();
#pragma omp parallel shared(tree)
{
#pragma omp single nowait
freeTreePar(tree);
}
end = std::chrono::system_clock::now();
std::chrono::duration<double> elapsed_seconds = end-start;
std::time_t end_time = std::chrono::system_clock::to_time_t(end);
std::cout << "finished computation at " << std::ctime(&end_time)
<< "elapsed time: " << elapsed_seconds.count() << "sn";
return 0;
}
当我运行此代码时,大约需要 0.38 秒才能释放树。但是,如果我直接致电freeTree(root)
,则仅需 0.2 秒。因此,即使树非常大(2^22个元素),即使在此特定的测试用例中,任务的大小相等,我也无法使用并行方法获得性能提高。
我做错了什么吗?您知道我如何改进此代码吗?谢谢!
某些任务并不是真正可行的,因为某些资源只能一次通过一个线程访问(线程安全)。这就是动态内存的情况。
malloc/free现在主要是线程安全。
=>将在每个Malloc/Free周围执行一个锁。
因此,您无法轻易改进此类代码。
相关文章:
- 通过递归进行因子分解
- 递归函数计算序列中的平方和(并输出过程)
- 使用递归的数组的最小值.这是怎么回事
- 递归列出所有目录中的C++与Python与Ruby的性能
- 递归计数给定目录的文件和所有目录
- 如何在BST的这个简单递归实现中消除警告
- C++:正在检查LinkedList中的回文-递归方法-错误
- 递归模板化函数不能分配给具有常量限定类型"const tt &"的变量"state"
- 递归无序映射
- TSP递归解的迭代形式
- 如何在Elixir中调用递归函数并行
- 返回递归调用和仅递归调用的区别
- 数组元素打印的递归方法
- 使用递归时获取变量的奇怪值
- 递归求和任务的错误答案
- 将目标数字拆分为一系列数字(递归任务)
- OpenMP:即使在深度极限的情况下,递归任务也比顺序慢
- 多线程递归任务同步
- 在TBB中使用递归、基于任务的并行编程获得不同的输出
- OpenMP递归任务