2017-05-25 25 views
0

我想用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线程。然后mainfor-loop将占用8线程,在每个线程中,func将被调用,因此应该使用附加2线程。从我的计算来看,我认为24线程就足够了。但在实际运行中,总共有线程生成了208

所以我的问题如下:
(1)为什么如此多的线程创建,虽然24似乎不够?
(2)是否有可能修复线程数量(例如,与内核数量相同)并在空闲时调度任务?

回答

0

1)这只是被定义为parallel指令后面紧跟loop指令的方式parallel for。所以基于工作共享粒度的线程创建没有限制。

编辑:澄清的OpenMP将:

  1. 创建线程的实现定义的量 - unless you specify otherwise
  2. 附表循环迭代这个团队的线程之间共享。你现在最终在团队中没有工作的线程。
  3. 如果您有嵌套并行性,将会重复:单个线程遇到新的嵌套并行构造,并将创建一个全新的团队。

所以在你的情况下,8个线程会遇到内部并行构造,每个产生24个新线程,而外部循环的16个线程则不会。所以你总共有8 * 24 + 16 = 208个线程。

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

+0

“这就是'parallel for'被定义为一个并行指令后立即跟着一个'loop'指令的方式,所以不存在基于工作共享粒度的线程创建限制。 。如果可能,你能否详细说明一下?谢谢! –

+0

@南晓我回答了我的问题。 – Zulan

0

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

所以你可以做的是要么需要较少的线程数量,如果你需要较少的线程,或使用其他一些可以动态管理活动线程的并行化技术。例如,如果要求8个线程用于外部并行和3个线程用于内部区域,则可以使用OpenMP,最多可使用24个线程(如果线程可以重新使用,例如当并行区域不同时运行时可以重新使用线程)。

- 安德烈

0

你应该尝试

#pragma omp task 

之外,在我看来,应避免使用嵌套OMP线程。

相关问题