title: Is it possible to remove the following !$OMP CRITICAL regions
body: <p>I have a fortran code that shows some very unsatisfactory performance due to some $OMP CRITICAL regions. This question is actually more about how to the critical regions can be avoided and whether those regions can be removed? In those critical regions I am updating counters and reading/writing values to an array</p>
  
  <pre><code>    i=0
      j=MAX/2
      total = 0
  
      !$OMP PARALLEL PRIVATE(x,N)
  
      MAIN_LOOP:do
      $OMP CRITICAL
          total = total + 1
          x = array(i)
          i = i + 1
          if ( i &gt; MAX) i=1 ! if the counter is past the end start form the beginning 
      $OMP END CRITICAL
          if (total &gt; MAX_TOTAL) exit
  
      ! do some calculations here and get the value of the integer (N)
      ! store (N) copies of x it back in the original array with some offset
  
      !$OMP CRITICAL
      do p=1,N
      array(j)=x
      j=j+1
      if (j&gt;MAX) j=1
      end do
      !$OMP END CRITICAL
  
   end do MAIN_LOOP
   $OMP END PARALLEL
  </code></pre>
  
  <p>One simple thing that came to my mind is to eliminate the counter on <code>total</code> by using explicit dynamic loop scheduling.</p>
  
  <pre><code>!$OMP PARALLEL DO SCHEDULE(DYNAMIC) 
  MAIN_LOOP:do total = 1,MAX_TOTAL
    ! do the calculation here
  end do MAIN_LOOP
  !$OMP END PARALLEL DO 
  </code></pre>
  
  <p>I was also thinking to allocate different portion of the <code>array</code> to each thread and using the thread <code>ID</code> to do offsetting. This time each processor will have it's own counter which will be stored in an array <code>count_i(ID)</code> and something of the sort</p>
  
  <pre><code>!this time the size if array is NUM_OMP_THREADS*MAX
     x=array(ID + sum(count_i)) ! get the offset by summing up all values
     ID=omp_get_thread_num()
     count_i(ID)=count_i(ID)+1
  if (count_i(ID) &gt; MAX) count_i(ID) = 1
  </code></pre>
  
  <p>This however will mess the order and will not do the same as the original method. Moreover some empty space will be present, since the different threads will not able to fit the entire range <code>1:MAX</code></p>
  
  <p>I would appreciate your help and ideas. </p>