首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OpenMP:将所有线程分成不同的组

OpenMP:将所有线程分成不同的组
EN

Stack Overflow用户
提问于 2014-08-28 19:40:23
回答 1查看 2.5K关注 0票数 2

我想将所有线程分成两个不同的组,因为我有两个并行任务要异步运行。例如,如果总共有8个线程可用,我将喜欢6个专用于task1的线程,另2个专用于task2的线程。

如何使用OpenMP实现这一目标?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-08-29 02:56:13

这是OpenMP嵌套并行的一项任务,从OpenMP 3开始:您可以使用OpenMP任务启动两个独立的任务,然后在这些任务中有使用适当数量线程的并行部分。

作为一个简单的例子:

代码语言:javascript
复制
#include <stdio.h>
#include <omp.h>

int main(int argc, char **argv) {

    omp_set_nested(1);   /* make sure nested parallism is on */
    int nprocs = omp_get_num_procs();
    int nthreads1 = nprocs/3;
    int nthreads2 = nprocs - nthreads1;

    #pragma omp parallel default(none) shared(nthreads1, nthreads2) num_threads(2)
    #pragma omp single
    {
        #pragma omp task
        #pragma omp parallel for num_threads(nthreads1)
        for (int i=0; i<16; i++)
            printf("Task 1: thread %d of the %d children of %d: handling iter %d\n",
                        omp_get_thread_num(), omp_get_team_size(2),
                        omp_get_ancestor_thread_num(1), i);
        #pragma omp task
        #pragma omp parallel for num_threads(nthreads2)
        for (int j=0; j<16; j++)
            printf("Task 2: thread %d of the %d children of %d: handling iter %d\n",
                        omp_get_thread_num(), omp_get_team_size(2),
                        omp_get_ancestor_thread_num(1), j);
    }

    return 0;
}

在一个8核(16个硬件线程)节点上运行它,

代码语言:javascript
复制
$ gcc -fopenmp nested.c -o nested -std=c99
$ ./nested
Task 2: thread 3 of the 11 children of 0: handling iter 6
Task 2: thread 3 of the 11 children of 0: handling iter 7
Task 2: thread 1 of the 11 children of 0: handling iter 2
Task 2: thread 1 of the 11 children of 0: handling iter 3
Task 1: thread 2 of the 5 children of 1: handling iter 8
Task 1: thread 2 of the 5 children of 1: handling iter 9
Task 1: thread 2 of the 5 children of 1: handling iter 10
Task 1: thread 2 of the 5 children of 1: handling iter 11
Task 2: thread 6 of the 11 children of 0: handling iter 12
Task 2: thread 6 of the 11 children of 0: handling iter 13
Task 1: thread 0 of the 5 children of 1: handling iter 0
Task 1: thread 0 of the 5 children of 1: handling iter 1
Task 1: thread 0 of the 5 children of 1: handling iter 2
Task 1: thread 0 of the 5 children of 1: handling iter 3
Task 2: thread 5 of the 11 children of 0: handling iter 10
Task 2: thread 5 of the 11 children of 0: handling iter 11
Task 2: thread 0 of the 11 children of 0: handling iter 0
Task 2: thread 0 of the 11 children of 0: handling iter 1
Task 2: thread 2 of the 11 children of 0: handling iter 4
Task 2: thread 2 of the 11 children of 0: handling iter 5
Task 1: thread 1 of the 5 children of 1: handling iter 4
Task 2: thread 4 of the 11 children of 0: handling iter 8
Task 2: thread 4 of the 11 children of 0: handling iter 9
Task 1: thread 3 of the 5 children of 1: handling iter 12
Task 1: thread 3 of the 5 children of 1: handling iter 13
Task 1: thread 3 of the 5 children of 1: handling iter 14
Task 2: thread 7 of the 11 children of 0: handling iter 14
Task 2: thread 7 of the 11 children of 0: handling iter 15
Task 1: thread 1 of the 5 children of 1: handling iter 5
Task 1: thread 1 of the 5 children of 1: handling iter 6
Task 1: thread 1 of the 5 children of 1: handling iter 7
Task 1: thread 3 of the 5 children of 1: handling iter 15

更新的:我已经将上面的内容更改为包含线程祖先;出现了混淆,因为(例如)打印了两个“线程1”--这里我还打印了祖先(例如,“1的5个子线程中的一个线程1与0的11个子线程1中的线程1”)。

OpenMP标准 S.3.2.4中,“omp_get_thread_num例程返回调用线程的当前团队中的线程号”,以及第2.5节,“当线程遇到并行构造时,创建一个线程组来执行并行区域.遇到并行构造的线程将成为新团队的主线程,在新的并行区域的持续时间内线程数为零。“

也就是说,在这些(嵌套的)并行区域中,创建的线程组的线程is从零开始;但仅仅因为这些is在团队中重叠并不意味着它们是相同的线程。这里我强调了,通过打印它们的祖先编号,但是如果线程正在执行CPU密集型的工作,您也会看到使用监视工具确实有16个活动线程,而不仅仅是11个。

它们是团队本地线程号而不是全局唯一线程号的原因非常简单;在可以发生嵌套和动态并行的环境中,几乎不可能跟踪全局唯一的线程号。假设有三个线程组,编号为0..5、6、..10和11.15,中间组完成。我们是否在线程编号中留下空白?我们是否中断所有线程以更改它们的全局编号?如果一个有7个线程的新团队启动了呢?我们是从6开始,有重叠的线程in,还是从16开始,在编号中留下空白?

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25556748

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档