Closest to what you want is OpenMP tasks, available in compatible OpenMP v3.0 compilers and later. It looks like this:
#pragma omp parallel { #pragma omp single for (int i = 0; i < 50; i++) { doStuff(); #pragma omp task callback(i); } }
This code will make the loop run in only one thread, and it will create 50 OpenMP tasks that will call callback() with different parameters. Then he will wait for the completion of all tasks before leaving the parallel area. Tasks will be selected (possibly randomly) by the idle threads that will be executed. OpenMP imposes an implicit barrier at the end of each parallel region, because its fork model provides that only the main thread runs outside the parallel regions.
Here is an example program ( ompt.cpp ):
#include <stdio.h> #include <unistd.h> #include <omp.h> void callback (int i) { printf("[%02d] Task stated with thread %d\n", i, omp_get_thread_num()); sleep(1); printf("[%02d] Task finished\n", i); } int main (void) { #pragma omp parallel { #pragma omp single for (int i = 0; i < 10; i++) { #pragma omp task callback(i); printf("Task %d created\n", i); } } printf("Parallel region ended\n"); return 0; }
Compilation and execution:
$ g++ -fopenmp -o ompt.x ompt.cpp $ OMP_NUM_THREADS=4 ./ompt.x Task 0 created Task 1 created Task 2 created [01] Task stated with thread 3 [02] Task stated with thread 2 Task 3 created Task 4 created Task 5 created Task 6 created Task 7 created [00] Task stated with thread 1 Task 8 created Task 9 created [03] Task stated with thread 0 [01] Task finished [02] Task finished [05] Task stated with thread 2 [04] Task stated with thread 3 [00] Task finished [06] Task stated with thread 1 [03] Task finished [07] Task stated with thread 0 [05] Task finished [08] Task stated with thread 2 [04] Task finished [09] Task stated with thread 3 [06] Task finished [07] Task finished [08] Task finished [09] Task finished Parallel region ended
Note that tasks are not performed in the same order in which they were created.
GCC does not support OpenMP 3.0 in versions older than 4.4. Unrecognized OpenMP directives are silently ignored, and as a result, the executable will have the following code:
$ g++-4.3 -fopenmp -o ompt.x ompt.cpp $ OMP_NUM_THREADS=4 ./ompt.x [00] Task stated with thread 3 [00] Task finished Task 0 created [01] Task stated with thread 3 [01] Task finished Task 1 created [02] Task stated with thread 3 [02] Task finished Task 2 created [03] Task stated with thread 3 [03] Task finished Task 3 created [04] Task stated with thread 3 [04] Task finished Task 4 created [05] Task stated with thread 3 [05] Task finished Task 5 created [06] Task stated with thread 3 [06] Task finished Task 6 created [07] Task stated with thread 3 [07] Task finished Task 7 created [08] Task stated with thread 3 [08] Task finished Task 8 created [09] Task stated with thread 3 [09] Task finished Task 9 created Parallel region ended
source share