在不平衡树上拆分 OpenMP 线程

2024-04-18

我正在尝试使用 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(使用前将#替换为@)

在不平衡树上拆分 OpenMP 线程 的相关文章

随机推荐