TutorialsTutorials HomeOpenMPIndexIntroduction PARALLEL DO PARALLEL DO SECTIONS SINGLE MASTER CRITICAL BARRIER FLUSH ATOMIC ORDERED
FullDocument
Related InfoOpenMP Home Page |
CRITICAL DirectiveThe CRITICAL and END CRITICAL directives restrict access to the enclosed code to only one thread at a time. A thread waits at the beginning of the critical section until no other thread in the team is executing a critical section with the same name. !$OMP CRITICAL [(name)] block !$OMP END CRITICAL [(name)] Bad ExampleThe following example will cause problems without the use of a critical region.
!Filename: critical.f90
!
!This shows use of the CRITICAL directive.
!
PROGRAM CRITICAL
IMPLICIT NONE
INTEGER:: L,I
INTEGER:: nthreads, OMP_GET_NUM_THREADS
L=10
!$OMP PARALLEL SHARED(L) PRIVATE(nthreads,I)
!$OMP MASTER
nthreads = OMP_GET_NUM_THREADS()
PRINT *, "Number of threads:",nthreads
!$OMP END MASTER
!*** The following is going to cause problems without a
!*** CRITICAL directive
CALL ADD_ONE(L)
!$OMP END PARALLEL
PRINT *, "The final value of L is", L
END PROGRAM CRITICAL
SUBROUTINE ADD_ONE(I)
IMPLICIT NONE
INTEGER, INTENT(INOUT):: I
INTEGER:: J, K
J = I
!$OMP MASTER
OPEN(UNIT=26,FORM='FORMATTED',FILE='junk')
DO K=1,40000
WRITE(26,*) "Hi Mom!"
END DO
CLOSE(26)
!$OMP END MASTER
J = J + 1
I = J
END SUBROUTINE ADD_ONE
We can see the problem by compiling and running on franklin.
> cat critical.pbs
#PBS -N critical
#PBS -j oe
#PBS -o critical.out
#PBS -q interactive
#PBS -S /bin/bash
#PBS -l mppwidth=1
#PBS -l mppnppn=1
#PBS -l mppdepth=2
#PBS -l walltime=00:05:00
#PBS -V
cd $PBS_O_WORKDIR
ftn -o critical -mp=nonuma -Minfo=mp critical.f90
export OMP_NUM_THREADS=2
for i in 1 2 3 4 5
do
echo "run $i of critical"
aprun -n 1 -N 1 ./critical
done
> qsub critical.pbs
500824.nid00003
> cat critical.out
/opt/xt-pe/2.0.44a2/bin/snos64/ftn: INFO: linux target is being used
critical.f90:
critical:
13, Parallel region activated
15, Begin master section
18, End master section
23, Parallel region terminated
add_one:
39, Begin master section
45, End master section
run 1 of critical
Number of threads: 2
The final value of L is 11
Application 4735728 resources: utime 2, stime 0
run 2 of critical
Number of threads: 2
The final value of L is 12
Application 4735729 resources: utime 1, stime 0
run 3 of critical
Number of threads: 2
The final value of L is 11
Application 4735730 resources: utime 1, stime 0
run 4 of critical
Number of threads: 2
The final value of L is 11
Application 4735731 resources: utime 1, stime 0
run 5 of critical
Number of threads: 2
The final value of L is 11
Application 4735732 resources: utime 1, stime 0
Not only do we not get the expected answer of 12 each time (10 + the number of threads), but we get different answers for different runs. What's the problem? The error occurs when we call the subroutine ADD_ONE, which adds one to the shared variable L. Each thread passes the address of L at the time it gets to the ADD_ONE call. But the order in which that happens is undefined. One thread makes the call while another is the process of doing the addition but has not yet updated the value. The result is indeterminate. (The "Hi Mom!" write statement is there just to ensure that the threads get well out of synch.) We can fix the problem (although perhaps not efficiently) by allowing only one thread at a time to update the value of L. We do this by using a CRITICAL region. Example (fixed). . . !$OMP CRITICAL CALL ADD_ONE(L) !$OMP END CRITICAL . . . Now we get the right answer consistently
> cat critical_fixed.pbs
#PBS -N critical_fixed
#PBS -j oe
#PBS -o critical_fixed.out
#PBS -q interactive
#PBS -S /bin/bash
#PBS -l mppwidth=1
#PBS -l mppnppn=1
#PBS -l mppdepth=2
#PBS -l walltime=00:05:00
#PBS -V
cd $PBS_O_WORKDIR
ftn -o critical_fixed -mp=nonuma -Minfo=mp critical_fixed.f90
export OMP_NUM_THREADS=2
for i in 1 2 3 4 5
do
echo "run $i of critical_fixed"
aprun -n 1 -N 1 ./critical_fixed
done
> qsub critical_fixed.pbs
500850.nid00003
> cat critical_fixed.out
/opt/xt-pe/2.0.44a2/bin/snos64/ftn: INFO: linux target is being used
critical_fixed.f90:
critical:
13, Parallel region activated
15, Begin master section
18, End master section
24, Begin critical section __cs_unspc
End critical section __cs_unspc
Parallel region terminated
add_one:
41, Begin master section
47, End master section
run 1 of critical_fixed
Number of threads: 2
The final value of L is 12
Application 4735856 resources: utime 1, stime 0
run 2 of critical_fixed
Number of threads: 2
The final value of L is 12
Application 4735857 resources: utime 0, stime 0
run 3 of critical_fixed
Number of threads: 2
The final value of L is 12
Application 4735858 resources: utime 1, stime 0
run 4 of critical_fixed
Number of threads: 2
The final value of L is 12
Application 4735859 resources: utime 1, stime 0
run 5 of critical_fixed
Number of threads: 2
The final value of L is 12
Application 4735860 resources: utime 1, stime 0
as expected. |
![]() |
Page last modified: Mon, 05 May 2008 21:14:43 GMT Page URL: http://www.nersc.gov/nusers/help/tutorials/openmp/critical.php Web contact: webmaster@nersc.gov Computing questions: consult@nersc.gov Privacy and Security Notice |
![]() |