簡體   English   中英

OpenMP - 使用 nowait 運行單個區域,然后在 for 循環中加入其他線程

[英]OpenMP - Run single region with nowait and after join other threads in for loop

What I'm trying to do is that the first part of the function runs in a single thread and other thread start the second function (this function has three loops) and after the single thread ends the first function he join with others to help with循環。

我編寫了以下代碼,這是錯誤的,因為所有線程都運行第二個 function,並且只需要一個即可運行,但所有線程都有助於循環。

void main(){


/* code */


#pragma omp parallel
{
     #pragma omp single nowait
     {
      std::cout << "Running func 1:" << omp_get_thread_num() << std::endl;
      func1();
      std::cout << "Finish func 1" <<std::endl;
     }

#pragma omp nowait

std::cout << "Running func 2:" << omp_get_thread_num() << std::endl;
func2();

#pragma omp barrier
}//close parallel


/* more code */

}//close main



void func2(void){

        /* code to read file */ 



#pragma omp parallel
{


     for (int i=40;i<60;i++){
          #pragma omp for nowait
          for (int j=0;j<100;j++){
           /* code  */
          }
      }

#pragma omp for schedule(dynamic,1) nowait
  for (int i=0;i<40;i++){
        for (int j=0;j<100;j++){
         /* code  */
       }
  }

#pragma omp for schedule(dynamic)
  for (int i=60;i<100;i++){
        for (int j=0;j<100;j++){
         /* code  */
        }
  }

         /* code to write file */ 

}//close parallel

#pragma omp barrier
} //close func2

我的終端顯示:

Running func 1: 0
Running func 2: 1
Running func 2: 2
Running func 2: 3 
Finish func 1
Running func 2: 0 

編輯

Obs.: Func1 應該只在一個線程上執行

func2 被分成三個 for 循環,因為第一個 for 比其他所有循環消耗更多的時間。 如果我只使用一個 for 循環,所有其他線程將結束,一些線程將繼續運行。 這樣,首先計算困難。

使用 Jim Cownie 建議的代碼,func1 和 func2 並行運行,但是要么線程運行 func2 兩次,要么只有一個線程單獨運行而無需其他線程的幫助。

即使有必要使用任務或部分,我有什么想法嗎?

您的代碼有很多問題

  1. 沒有像#pragma omp nowait這樣的 openMP 指令,因此您甚至可能沒有在啟用 OpenMP 的情況下進行編譯(因為,當它啟用時,您應該收到一條錯誤消息;例如,請參閱https://godbolt.org/z/EbYV6h )
  2. 在並行區域結束之前永遠不需要#pragma omp barrier (因為將執行下一個串行區域的主線程在所有線程也完成並行區域中的執行之前不能離開。)

我不明白你為什么要使用嵌套並行。 您已經在並行執行 func2() ,因此此處的任何嵌套都會導致超額訂閱。

你可以像這樣實現你想要的

#pragma omp parallel
{
#pragma omp single nowait
    func1()
  func2();
}

void func2()
{
#pragma omp for schedule(dynamic), nowait
    for (...)
        ... etc ...
}

或者,通過使用任務和任務循環,這可能是一種更簡潔的表達方式。

使用任務,(並且,在你澄清你只希望function2執行一次之后(我正在閱讀代碼所說的,因為這比讀心更容易,)),這樣的事情有效

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

void function1()
{
  fprintf(stderr,"%d: entering function1\n", omp_get_thread_num());
  sleep(1);
  fprintf(stderr,"%d: leaving function1\n", omp_get_thread_num());
}

void function2()
{
  fprintf(stderr,"%d: entering function2\n", omp_get_thread_num());
#pragma omp taskloop grainsize(1)                                                                                   
  for (int i=0; i<10; i++)
    {
      fprintf(stderr,"%d: starting iteration %d\n",
                     omp_get_thread_num(),i);
      sleep(1);
      fprintf(stderr,"%d: finishing iteration %d\n",
                     omp_get_thread_num(),i);
    }
  fprintf(stderr,"%d: leaving function2\n", omp_get_thread_num());
}

int main()
{
#pragma omp parallel
  {
#pragma omp single
    {
      fprintf(stderr,"Executing with %d threads\n",
                      omp_get_num_threads());
#pragma omp task
      {
        function1();
      }
#pragma omp task
      {
        function2();
      }
    }
  }
}

這是在四個線程上執行,當然其他交錯也是可能的。

OMP_NUM_THREADS=4 ./a.out
Executing with 4 threads
3: entering function2
2: entering function1
0: starting iteration 0
1: starting iteration 1
3: starting iteration 9
1: finishing iteration 1
3: finishing iteration 9
0: finishing iteration 0
3: starting iteration 8
1: starting iteration 2
2: leaving function1
0: starting iteration 3
2: starting iteration 4
3: finishing iteration 8
1: finishing iteration 2
3: starting iteration 7
0: finishing iteration 3
0: starting iteration 6
2: finishing iteration 4
1: starting iteration 5
0: finishing iteration 6
3: finishing iteration 7
1: finishing iteration 5
3: leaving function2

您可以看到只有一個線程執行每個函數[12],並且循環迭代在所有線程中共享。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM