The BARRIER directive enables you to synchronize all threads in a team. When a thread encounters a BARRIER directive, it will wait until all other threads in the team reach the same point.
The BARRIER directive only takes effect if you specify the -qsmp compiler option.
A BARRIER directive binds to the closest dynamically enclosing PARALLEL directive, if one exists.
A BARRIER directive cannot appear within the dynamic extent of the CRITICAL, DO (worksharing), MASTER, PARALLEL DO , PARALLEL SECTIONS, SECTIONS, SINGLE and WORKSHARE directives.
All threads in the team must encounter the BARRIER directive if any thread encounters it.
All BARRIER directives and work-sharing constructs must be encountered in the same order by all threads in the team.
In addition to synchronizing the threads in a team, the BARRIER directive implies the FLUSH directive. This means it causes thread visible variables to be written back to memory. Thread visible variables are variables that are or might be SHARED for the PARALLEL construct containing the BARRIER directive, and that are accessible in the scoping unit containing the BARRIER directive.
Example 1: An example of the BARRIER directive binding to the PARALLEL directive. Note: To calculate "c", we need to ensure that "a" and "b" have been completely assigned to, so threads need to wait.
SUBROUTINE SUB1 INTEGER A(1000), B(1000), C(1000) !$OMP PARALLEL !$OMP DO DO I = 1, 1000 A(I) = SIN(I*2.5) END DO !$OMP END DO NOWAIT !$OMP DO DO J = 1, 10000 B(J) = X + COS(J*5.5) END DO !$OMP END DO NOWAIT
!$OMP BARRIER C = A + B !$OMP END PARALLEL END
Example 2: An example of a BARRIER directive that incorrectly appears inside a CRITICAL section. This can result in a deadlock since only one thread can enter a CRITICAL section at a time.
!$OMP PARALLEL DEFAULT(SHARED) !$OMP CRITICAL DO I = 1, 10 X= X + 1 !$OMP BARRIER Y= Y + I*I END DO !$OMP END CRITICAL !$OMP END PARALLEL