簡體   English   中英

為函數創建openmp線程

[英]creating openmp threads for functions

我看到的所有openmp教程示例都是為for循環創建線程。 但是我需要為可能聚集到函數中的普通語句組創建線程。 例如,如下所示:

#include <stdio.h>
#include <omp.h>
int A() { printf("in A:%d\n", omp_get_thread_num()); }
int B() { printf("in B:%d\n", omp_get_thread_num()); }
int D() { printf("in D:%d\n", omp_get_thread_num()); }
int E() { printf("in E:%d\n", omp_get_thread_num()); }
int F() { printf("in F:%d\n", omp_get_thread_num()); }
int G() { printf("in G:%d\n", omp_get_thread_num()); }
int H() { printf("in H:%d\n", omp_get_thread_num()); }
int C() {
    printf("in C:%d\n", omp_get_thread_num());
    #pragma omp parallel num_threads(2)
    {
        D(); // want to execute D,E in separate threads
        E();
    }
    F();
}
main() {
    omp_set_nested(1);
    printf("in main:%d\n", omp_get_thread_num());
    G();
    #pragma omp parallel num_threads(3)
    {
        A(); // want to execute A,B,C in separate threads
        B();
        C();
    }
    H();
}

在上面的代碼中,我希望每個函數僅在不同的線程中執行一次。 (因此,在上述代碼中使用指令可能是錯誤的,請根據需要對其進行更正。)

我該如何用openmp編碼這種嵌套的函數並行性? 這些函數將共享所有可用的全局變量,還是有辦法指定哪些變量將由哪些函數共享?

編輯:閱讀下面Jorge Bellon的回答后,我編寫了以下代碼,其輸出顯示在代碼之后。 看起來線程0正在用於許多功能,這不是我想要的-我希望這些功能可以並行執行。 另外,我只希望對G執行一次,因此看起來我必須刪除“ num_threads(3)”行。 讓我知道解決此問題的方法是什么。

// compile this with: g++ -fopenmp
int A() { printf("in H:%d\n", omp_get_thread_num()); sleep(1); }
// similarly for B, D, E, F, G, H
int C() {
    printf("in C:%d\n", omp_get_thread_num()); sleep(1);
    #pragma omp task
    D();
    #pragma omp task
    E();
    #pragma omp taskwait
    F(); sleep(1);
}
main() {
    omp_set_nested(1);
    printf("in main:%d\n", omp_get_thread_num());
    #pragma omp parallel num_threads(3)
    G();
    #pragma omp task
    A();
    #pragma omp task
    B();
    #pragma omp task
    C();
    #pragma omp taskwait
    H();
}
// outputs:
in main:0
in G:1
in G:0
in G:2
in A:0
in B:0
in C:0
in D:0
in E:0
in F:0
in H:0

並行化此類代碼的最佳方法是使用OpenMP task構造。 您的並行區域將創建一個線程池,一個主線程將創建外部任務,其余線程將在這些任務可用時立即對其進行處理。

// [...]

int C() {
  // You can create tasks within tasks
  // In this example is better to place {D,E} and {E} in tasks
  // and omit the task construct of C function call
  #pragma omp task
  {
    D();
    E();
  }
  // if F() needs D and E to finish, a taskwait is necessary
  F();
}

main() {
  // omp_set_nested no longer necessary
  printf("in main:%d\n", omp_get_thread_num());
  G();
  #pragma omp parallel num_threads(3)
  #pragma omp single
  {
    // a single thread creates the tasks
    // other threads in the team will be able to execute them
    // want to execute A,B,C in separate threads
    #pragma omp task
    A();
    #pragma omp task
    B();
    #pragma omp task
    C();
    // wait until all the tasks have been finished
    #pragma omp taskwait
  }
  H();
}

每個函數是否在不同的線程中執行完全取決於運行時程序的狀態。 這意味着,如果所有其他線程都處於繁忙狀態,則某些任務可以在同一線程中執行,這不是特別重要的問題。

您可以使用任務依賴性 (從OpenMP 4開始)來控制是否允許任務在創建時繼續執行。

以下解決方案是使用c ++ 11線程實現的。 詳細的openmp版本尚待制定。

// compile this with: g++ -pthread -std=gnu++0x
#include <stdio.h>
#include <unistd.h> // for sleep
#include <thread>
#include <iostream>
#include <sstream>
using namespace std;
int A() { stringstream ss; ss << this_thread::get_id();
          printf("in A:%s\n", ss.str().c_str()); sleep(1); }
// similarly for B, D, E, F, G, H
int C() {
    stringstream ss; ss << this_thread::get_id();
    printf("in C:%s\n", ss.str().c_str()); sleep(1);
    std::thread thread_1(D);
    std::thread thread_2(E);
    thread_1.join();
    thread_2.join();
    F(); sleep(1);
}
main() {
    printf("in main\n");
    G();
    std::thread thread_1(A);
    std::thread thread_2(B);
    std::thread thread_3(C);
    thread_1.join();
    thread_2.join();
    thread_3.join();
    H();
}
// outputs:
in main
in G:0x600000060
in A:0x60005aa10
in B:0x60005ab10
in C:0x60005ae40
in D:0x60005af40
in E:0x60005b040
in F:0x60005ae40
in H:0x600000060

暫無
暫無

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

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