如何在同一时间启动具有不同线程功能的两个线程组?

问题描述:

我有两组线程,一组由n个线程执行,另一组由m个线程执行。我想在同一时间启动它们,但我得到的是,该组第1分开始,然后组2如何在同一时间启动具有不同线程功能的两个线程组?

//group 1 
#pragma omp parallel num_threads(n) 
{ 
    #pragma omp for 
    for (int i = 0; i < n; i++) { 
     function1(i); 
    } 
} 
//group 2 
#pragma omp parallel num_threads(m) 
{ 
    #pragma omp for 
    for (int i = 0; i < m; i++) { 
     function2(i); 
    } 
} 

我得到的输出是:

function1 is called 
function1 is called 
function1 is called 
... 
n 
function2 is called 
... 
m 

我期望的输出(只是随便举个例子):

function2 is called 
function2 is called 
function1 is called 
function2 is called 
function1 is called 
... 
+0

只要有是一些让你指定许多事情的结构,并且它们在同一时间完成了它们,你可以使用某种并行循环。 –

+0

这将严重依赖于您的操作系统正在使用的调度程序的时间片等事情,以及您是否正在使用多个内核以及许多您可能不想处理的内容。你应该问这个问题,你为什么要这样做? –

在你的榜样,您遇到的行为正好是一个可以预料到的,因为2个parallel地区依次创造了一个又下。

如果您想坚持使用parallel for构造的方法,则需要将它们放入另一个parallel构造中,并允许嵌套并行。这可能给这个例如:

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

void function1(int i) { 
    printf("Function1(%d)\n", i); 
    usleep((i * 1237 + 8765) % 9797); 
} 

void function2(int i) { 
    printf("Function2(%d)\n", i); 
    usleep((i * 7321 + 5678) % 10903); 
} 

int main() { 

    int n = 10, m = 5; 
    omp_set_nested(1); 

    #pragma omp parallel sections num_threads(2) 
    { 
     #pragma omp section 
     #pragma omp parallel for num_threads(n) 
     for (int i = 0; i < n; i++) 
      function1(i); 
     #pragma omp section 
     #pragma omp parallel for num_threads(m) 
     for (int i = 0; i < m; i++) 
      function2(i); 
    } 

    return 0; 
} 

注意:我已经添加了一些伪随机等待里面的函数调用,以允许在返回一些延误,否则,看到错位输出的可能性非常渺茫。

在我的四核机,这给了我(例如):

~/tmp$ gcc -fopenmp pools.c 
~/tmp$ ./a.out 
Function2(2) 
Function1(5) 
Function1(1) 
Function2(1) 
Function2(0) 
Function1(0) 
Function1(3) 
Function1(4) 
Function1(6) 
Function1(9) 
Function1(7) 
Function2(4) 
Function1(2) 
Function1(8) 
Function2(3) 

所以这个回答您直接问,但我的感觉是,最初的方法可能不是最合适的一个。您应该明确考虑查看task结构,因为它可能更适合您想要实现的功能。

吉尔的回答是不错的,但我想抛出一些额外的想法:

既然你从线程函数有一个1对1映射,有一个很短的解决方案:

#pragma omp parallel number_threads(n + m) 
{ 
    assert(omp_get_num_threads() == n + m); 
    auto me = omp_get_thread_num(); 
    if (me < n) function1(me); 
    else function2(me - n); 
} 

但是 - 无论如何我建议小心。它可以在性能比核心(超额)多线程方面是非常危险的,宁愿留线程数的选择为OpenMP,且仍有不嵌套一个简单的解决方案:

#pragma omp parallel for 
for (int nm = 0; nm < n + m; nm++) { 
    if (nm < n) function1(nm); 
    else function2(nm - n); 
}