mercredi 6 septembre 2017

creating openmp threads for functions

All the tutorial examples for openmp that I see are for creating threads for for loops. But I need to create threads for ordinary groups of statements which may be clustered into functions. eg, something like the following:

#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();
}

In the above code, I want each function to execute exactly once, but in different threads. (So I might be wrong in the above code with the usage of the directives, please correct it as needed.)

How do I code this kind of nested parallelism of functions with openmp? Will these functions share all the global variables that are available, or is there a way to specify which variables will be shared by which functions?

EDITS: After reading Jorge Bellon's answer below, I coded the following, and its output is shown after the code. It looks like thread-0 is being used for many of the functions, which is not what I intended - I want the functions to be executed in parallel. Also, I want only one execution for G, so looks like I have to delete the "num_threads(3)" line. Let me know what is the fix for this problem.

// 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

Also, following Mark's advise, I tried the threads of c++-11. Again, the functions are getting called exactly once here, but how do I find out whether they are actually being executed in parallel?

// compile this with: g++ -pthread -std=gnu++0x
int A() { printf("in A\n"); sleep(1); }
// similarly for B, D, E, F, G, H
int C() {
    printf("in C\n"); 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
in A
in B
in C
in D
in E
in F
in H

Aucun commentaire:

Enregistrer un commentaire