[英]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 兩次,要么只有一個線程單獨運行而無需其他線程的幫助。
即使有必要使用任務或部分,我有什么想法嗎?
您的代碼有很多問題
#pragma omp nowait
這樣的 openMP 指令,因此您甚至可能沒有在啟用 OpenMP 的情況下進行編譯(因為,當它啟用時,您應該收到一條錯誤消息;例如,請參閱https://godbolt.org/z/EbYV6h )#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.