2017-10-19 130 views
1

我有兩組線程,一組由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

在你的榜樣,您遇到的行爲正好是一個可以預料到的,因爲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對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); 
} 
相關問題