3
\$\begingroup\$

What I basically want to do is this:

int main()
{
 const int n = 100;
 #pragma omp parallel for
 for (int i=0; i<n; i++)
 {
 int thread_ID = omp_get_thread_num();
 printf("%d) work 1 %d\n", thread_ID, i);
 #pragma omp barrier
 printf(" %d) work 2 %d\n", thread_ID, i);
 #pragma omp barrier
 }
 return 0;
}

except we cannot put a barrier into a parallel for in OpenMP; it just cannot be done. However, it's possible to explicitly do the separation between the threads in order to make it work:

#include <stdlib.h>
#include <stdio.h>
#include <omp.h>
int main()
{
 const int n = 100;
 int nthreads;
 #pragma omp parallel
 {
 // get the number of threads
 #pragma omp single
 {
 nthreads = omp_get_num_threads();
 }
 int thread_ID = omp_get_thread_num();
 // calculate which threads have to do one more iteration
 int one_more = thread_ID<(n%nthreads);
 int step = n/nthreads;
 int start, end;
 if(one_more){
 start = step*thread_ID + thread_ID;
 end = start + step + 1;
 }
 else{
 start = step*thread_ID + n%nthreads;
 end = start + step;
 }
 // the real work is here
 for (int i=start; i<start+step+1; i++)
 {
 if(i<end)
 printf("%d) work 1 %d\n", thread_ID, i);
 #pragma omp barrier
 if(i<end)
 printf(" %d) work 2 %d\n", thread_ID, i);
 #pragma omp barrier
 }
 }
 return 0;
}

However, I find this a bit dirty and I would have preferred something cleaner. Does somebody have a better idea?

Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Apr 5, 2017 at 8:19
\$\endgroup\$
2
  • \$\begingroup\$ What would the first program mean, if it meant something? barrier is used to ensure that the threads have all reached the same point in the code, but if that point is within a loop, threads may reach that point any number of times (including zero), and not necessarily the same number of times in all threads. Is the intent supposed to be that at any given time, work1 isn't being done at the same time as work2? It sounds like you just need a suitable mutex solution. Perhaps a bit more explanation of your motivation (use case) might help? \$\endgroup\$ Commented Apr 5, 2017 at 12:23
  • \$\begingroup\$ It would mean something if a barrier meant "all thread that did not terminate must reach this before continuing" and if it was allowed to put the barrier in the parallel loop obviously \$\endgroup\$ Commented Apr 5, 2017 at 13:25

1 Answer 1

3
\$\begingroup\$

You want to synchronize two parts of your iteration and parallelize the each one of them independently. A good option is splitting the code in two:

int main()
{
 const int n = 100;
 #pragma omp parallel
 {
 #pragma omp for
 for (int i=0; i<n; i++)
 {
 int thread_ID = omp_get_thread_num();
 printf("%d) work 1 %d\n", thread_ID, i);
 } // barrier (implicit, unless using 'nowait')
 #pragma omp for
 for (int i=0; i<n; i++)
 {
 printf(" %d) work 2 %d\n", thread_ID, i);
 } // barrier
 } // omp parallel
 return 0;
}
answered Feb 23, 2018 at 21:50
\$\endgroup\$
1
  • \$\begingroup\$ A really nice feature of this answer is that it will work the same way even if #pragma omp does nothing - which it could do if, for example, the code was compiled without the relevant compiler support flag such as -fopenmp. \$\endgroup\$ Commented Sep 8, 2023 at 4:07

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.