我想将所有线程分成两个不同的组,因为我有两个并行任务要异步运行。例如,如果总共有8个线程可用,我将喜欢6个专用于task1的线程,另2个专用于task2的线程。
如何使用OpenMP实现这一目标?
发布于 2014-08-29 02:56:13
这是OpenMP嵌套并行的一项任务,从OpenMP 3开始:您可以使用OpenMP任务启动两个独立的任务,然后在这些任务中有使用适当数量线程的并行部分。
作为一个简单的例子:
#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个硬件线程)节点上运行它,
$ 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开始,在编号中留下空白?
https://stackoverflow.com/questions/25556748
复制相似问题