1
votes

I have a loop executed on multiple threads. Each loop will store a value into a global vector. The vector index variable is used by all threads and each thread increments the index after vector update. The access to the index must be protected. How the protection is done in OpenMP?

1/ If I specify #pragma omp parallel shared(k) Will this protect (synchronize access to) k-index access across threads?

   int k = 0;
   #pragma omp parallel shared(k)
   for (int i = 1; i < d; ++i)
   {
      for (int j = 0; j < i; ++j)
      {
         my_vec[k++] = some_value; //no need to protect my_vector, if k is unique across trheads
      }
   }

2/ Do I need to use critical section

   int k = 0;
   #pragma omp parallel
   for (int i = 1; i < d; ++i)
   {
      for (int j = 0; j < i; ++j)
      {
        #pragma omp critical (section_name)
        {
           my_vec[k++] = some_value;
        }
      }
   }

3/do I need to use both, the shared clause and critical section block?

1

1 Answers

1
votes

1/ If I specify #pragma omp parallel shared(k) Will this protect (synchronize access to) k-index access across threads?

If you use a shared k you will have two race conditions:

  1. during the updates of the variable k, namely in the operation k++.
  2. during the access to the array my_vec during the operation my_vec[k++] = some_value;

Multiple threads with the same k index could rewrite each others value of my_vec[k].

AFAIK there is no condition where making a variable shared would avoid a race-condition. It is often the other way around; if you make a variable shared you might need to ensure that it is protected against concurrent thread updates.

2/ Do I need to use critical section

If you only use a critical section and the variable k is private among threads you would have a race-condition during the accesses to the array my_vec (during the operation my_vec[k++] = some_value;). Nonetheless, if nothing is specified otherwise (e.g., private(k)), by default OpenMP assumes that the variable k is shared among threads. Therefore, using a critical region is enough to ensure the mutual exclusion on the accesses to both shared variables (i.e., the variable k and the array my_vec)

3/do I need to use both, the shared clause and critical section block?

You can make it explicit that the variable k is shared but by default the option 2) is enough.