How to force openMP to iterate in a specific order

I use openMP to run instances of my simulation in parallel.

#pragma omp parallel for private(part) shared(P,lfcc,temp)
for (part = 0; part < P->Parts; part++)

Part of the loop checks if the output file already exists with the index number "part" (so I can run the simulation for the specific value "Parts" and then increase it without overwriting the existing results). However, this requires that the iteration be performed in order. That is, for n threads, it must first start parts (1) - (n), followed by parts (n + 1) - (2n), etc. right now (with 3 streams (N / 3), (2N / 3), followed by (1), (N / 3 + 1), (2N / 3 + 1), etc.

Suppose now that I initially wanted 30 parts that were completely completed. Then I decided that I needed more details and change the β€œParts” to 45. Then the first threads get the parts (1) - (15), the second (16) - (30) and the third (31-45). The first two threads quickly discover that all of their assigned parts are already completed and will leave the last thread alone (if I set the barrier condition before the program ends).

One simple solution is to allow the variable "part" to start not with 0, but with m + 1, where m is the number of previously completed parts. But I was wondering if it is possible to force openMP to iterate in the order shown in bold.

+6
source share
2 answers

, 1 schedule, . schedule(static,1). 0, 3, 6, 9 .., 1, 4, 7, 10 .., 2, 5, 8, 11 . - , , ( , ).

OpenMP. , . (, ):

#pragma omp parallel
{
    ...
    #pragma omp single
    for (part = 0; part < P->Parts; part++)
    {
        if (!output_file_exists(part))
           #pragma omp task
           {
              ... computation for that part ...
           }
    }
    #pragma omp taskwait
    ...
}

, .

+7

, OpenMP , ordered. . i ( ) (i 0 19, 0 omp_get_num_threads() - 1):

#pragma omp parallel
#pragma omp for ordered
for (i = 0; i < 20; i++)
    #pragma omp ordered
    printf("i=%d - tid=%d\n", i, omp_get_thread_num());

( 8- Intel x86_64):

i=0 - tid=0
i=1 - tid=0
i=2 - tid=0
i=3 - tid=1
i=4 - tid=1
i=5 - tid=1
i=6 - tid=2
i=7 - tid=2
i=8 - tid=2
i=9 - tid=3
i=10 - tid=3
i=11 - tid=3
i=12 - tid=4
i=13 - tid=4
i=14 - tid=5
i=15 - tid=5
i=16 - tid=6
i=17 - tid=6
i=18 - tid=7
i=19 - tid=7

:

#pragma omp parallel
#pragma omp for ordered
for (i = 0; i < 20; i++)
{
    // the threads enter this for() section in order but won't 
    // print this statement in order!
    printf("other i=%d - tid=%d\n", i, omp_get_thread_num());
    #pragma omp ordered
    // these are printed in order
    printf("i=%d - tid=%d\n", i, omp_get_thread_num()); 
}

:

other i=16 - tid=6
other i=18 - tid=7
other i=12 - tid=4
other i=0 - tid=0
i=0 - tid=0
other i=1 - tid=0
i=1 - tid=0
other i=2 - tid=0
i=2 - tid=0
other i=3 - tid=1
other i=6 - tid=2
other i=14 - tid=5
i=3 - tid=1
other i=4 - tid=1
i=4 - tid=1
other i=5 - tid=1
i=5 - tid=1
i=6 - tid=2
other i=7 - tid=2
i=7 - tid=2
other i=8 - tid=2
i=8 - tid=2
other i=9 - tid=3
i=9 - tid=3
other i=10 - tid=3
i=10 - tid=3
other i=11 - tid=3
i=11 - tid=3
i=12 - tid=4
other i=13 - tid=4
i=13 - tid=4
i=14 - tid=5
other i=15 - tid=5
i=15 - tid=5
i=16 - tid=6
other i=17 - tid=6
i=17 - tid=6
i=18 - tid=7
other i=19 - tid=7
i=19 - tid=7

Finally, note that this array is populated in order:

// threads filling up array
int Arr[20] = {0};
#pragma omp parallel for ordered
for (i = 0; i < 20; i++)
    Arr[i] = i;

printf("\n\n");
// lets check to see if threads have put values to the array in order
for (i = 0; i < 20; i++)
    printf("Arr[%d]=%d\n", i, Arr[i]);

Output:

A[0]=0
A[1]=1
A[2]=2
A[3]=3
A[4]=4
A[5]=5
A[6]=6
A[7]=7
A[8]=8
A[9]=9
A[10]=10
A[11]=11
A[12]=12
A[13]=13
A[14]=14
A[15]=15
A[16]=16
A[17]=17
A[18]=18
A[19]=19
+3
source

All Articles