我正在尝试使用 OpenMP 并行进行树操作,例如对树中所有叶子中的数字进行求和。我遇到的问题是我工作的树不平衡(子节点的数量不同,分支的大小也不同)。
我目前在这些树上使用递归函数。我想要实现的是:
1)在第一个可能的机会时分割线程,假设它是一个有 2 个子节点的节点
2) 继续从两个结果线程中拆分至少 2-3 个级别,以便所有线程都在工作
它看起来像这样:
if (node->depth <= 3) {
#pragma omp parallel
{
#pragma omp schedule(dynamic)
for (int i = 0; i < node->children_no; i++) {
int local_sum;
local_sum = sum_numbers(node->children[i])
#pragma omp critical
{
global_sum += local_sum;
}
}
}
} else {
/*run the for loop without parallel region*/
}
这里的问题是,当我允许嵌套并行时,OpenMP 似乎在新团队中创建了很多线程。我想要实现的是:
1)创建新团队的每个线程不能占用超过 MAX_THREADS 的线程
2)一旦一个子树中的 for 循环结束,其他仍在更大子树中工作的 for 循环将接管现在空闲的线程以更快地完成其工作
这样,我希望线程永远不会多于必要的数量,但只要所有 for 循环中未完成的任务组合起来比创建的线程多,它们就一直在工作。
从文档来看,它看起来像并行仅使用已在并行区域中创建的线程。是否可以使其按描述的方式工作,或者我是否需要更改实现以首先列出各个分支的任务,然后对该列表运行并行 for 循环?
仅供记录,我将根据 High Performance Mark 的评论(我也同意这一评论)来写下这个问题的答案。即使树不平衡,此处使用 OpenMP 任务也会增加并行性的灵活性,支持递归性并为所有线程生成足够的工作(尽管您应该使用诸如Vampir http://tu-dresden.de/die_tu_dresden/zentrale_einrichtungen/zih/forschung/projekte/vampir, Paraver http://www.bsc.es/computer-sciences/performance-tools/paraver and/or 高性能计算工具包 http://hpctoolkit.org).
结果代码可能看起来像
if (node->depth <= 3) {
#pragma omp parallel shared (global_sum)
{
for (int i = 0; i < node->children_no; i++) {
int local_sum;
#pragma omp single
#pragma omp task
{
local_sum = sum_numbers(node->children[i])
#pragma omp critical
global_sum += local_sum;
}
}
}
} else {
/*run the for loop without parallel region*/
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)