是否可以修复线程数并在空闲时分派任务?

时间:2017-05-25 07:15:25

标签: multithreading parallel-processing openmp

我想使用OpenMP来达到这个效果:修复线程数,如果有空闲线程,则将任务分配给它,否则等待空闲线程。以下是我的测试代码:

#include <omp.h>
#include <stdio.h>
#include <unistd.h>

void func(void) {
    #pragma omp parallel for
    for (int i = 0; i < 3; i++)
    {
        sleep(30);
        printf("%d\n", omp_get_thread_num());
    }
}

int main(void) {
    omp_set_nested(1);
    omp_set_num_threads(omp_get_num_procs());
    #pragma omp parallel for
    for (int i = 0; i < 8; i++)
    {
        printf("%d\n", omp_get_thread_num());
        func();
    }   

    return 0;
}

实际上,我的机器包含24核心,所以

omp_set_num_threads(omp_get_num_procs())

将在开头启动24个帖子。然后main的{​​{1}}将占用for-loop个帖子,在每个帖子中,将调用8,因此应该使用额外的func个帖子。根据我的计算,我认为2线程就足够了。但在实际运行中,生成了24个线程。

所以我的问题如下:
(1)为什么208似乎已经创建了这么多线程呢? (2)是否可以修复线程数(例如,与核心数相同)并在有闲置时分派任务?

3 个答案:

答案 0 :(得分:1)

1)这就是parallel for被定义为parallel指令的方式,紧接着是loop指令。因此,基于工作共享粒度的线程创建没有限制。

编辑:澄清OpenMP将:

  1. 创建实现定义的线程数量 - unless you specify otherwise
  2. 在此线程团队中安排循环迭代的份额。你现在最终得到团队中没有工作的线程。
  3. 如果您有嵌套并行性,则会重复:单个线程遇到新的嵌套并行构造,并将创建一个全新的团队。
  4. 所以在你的情况下,8个线程遇到内部并行构造,每个构造产生24个新线程,并且外部循环的16个线程不会。所以你总共有8 * 24 + 16 = 208个主题。

    2)是的,顺便说一句,这个概念在OpenMP中被称为taskHere is a good introduction

答案 1 :(得分:0)

在OpenMP中,一旦您询问了特定数量的线程,运行时系统就会将它们提供给您的并行区域(如果能够这样做),并且这些线程在并行区域处于活动状态时不能用于其他工作。运行时系统无法猜测您不会使用您请求的线程。

因此,如果您需要较少的线程,或者使用其他可以动态管理活动线程数的并行化技术,您可以做的是要求较少数量的线程。例如,如果要求8个线程用于外部并行线程,3个线程用于内部区域,则使用OpenMP,您可以使用24个线程(如果线程可以重复使用,则更少,例如,当并行区域不同时运行时)。

- 安德烈

答案 2 :(得分:0)

你应该试试

#pragma omp task

此外,在我看来,避免使用嵌套的omp线程。

相关问题