S-21 /Print 2+/ S-2 printf("2:Thread#&d:x =$d\n",omp_get_thread_num(),x ) }else /Print 3t/ printf("3:Thread#&d:x &d\n",omp_get_thread_num(),x ) return 0; C/C++ Fortran Example mem_model.If -1 PROGRAM MEMMODEL INCLUDE "omp_lib.h" !or USE OMP_LIB S-3 INTEGER X -4 X=2 9 !SOMP PARALLEL NUM_THREADS(2)SHARED(X) S-8 IF (OMP_GET_THREAD_NUM().EQ.0)THEN s-9 =5 s-10 ELSE S-11 PRINT 1:The following read of x has a race S-12 PRINT *,"1:THREAD#"OMP_GET_THREAD_NUM ()"X ="x s-13 ENDIF S-14 s15 SOMP BARRIER S-16 s-17 IF (OMP_GET_THREAD_NUM().EQ.0)THEN S-18 PRINT 2 S-19 PRINT ,"2:THREAD#"OMP_GET_THREAD_NUM(),"X "X S-20 ES PRINT 3 PRINT *,"3:THREAD#"OMP_GET_THREAD_NUM(),"X ="x ENDIF !SOMP END PARALLEL END PROGRAM MEMMODEL Fortran The following example demonstrates why synchronization is difficult to perform correctly through 34 variables.The value of flag is undefined in both prints on thread I and the value of data is only well-defined in the second print. CHAPTER 2.THE OPENMP MEMORY MODEL 5
S-21 /* Print 2 */ S-22 printf("2: Thread# %d: x = %d\n", omp_get_thread_num(),x ); S-23 } else { S-24 /* Print 3 */ S-25 printf("3: Thread# %d: x = %d\n", omp_get_thread_num(),x ); S-26 } S-27 } S-28 return 0; S-29 } C / C++ Fortran 1 Example mem_model.1f S-1 PROGRAM MEMMODEL S-2 INCLUDE "omp_lib.h" ! or USE OMP_LIB S-3 INTEGER X S-4 S-5 X = 2 S-6 !$OMP PARALLEL NUM_THREADS(2) SHARED(X) S-7 S-8 IF (OMP_GET_THREAD_NUM() .EQ. 0) THEN S-9 X = 5 S-10 ELSE S-11 ! PRINT 1: The following read of x has a race S-12 PRINT *,"1: THREAD# ", OMP_GET_THREAD_NUM(), "X = ", X S-13 ENDIF S-14 S-15 !$OMP BARRIER S-16 S-17 IF (OMP_GET_THREAD_NUM() .EQ. 0) THEN S-18 ! PRINT 2 S-19 PRINT *,"2: THREAD# ", OMP_GET_THREAD_NUM(), "X = ", X S-20 ELSE S-21 ! PRINT 3 S-22 PRINT *,"3: THREAD# ", OMP_GET_THREAD_NUM(), "X = ", X S-23 ENDIF S-24 S-25 !$OMP END PARALLEL S-26 S-27 END PROGRAM MEMMODEL Fortran 2 The following example demonstrates why synchronization is difficult to perform correctly through 3 variables. The value of flag is undefined in both prints on thread 1 and the value of data is only 4 well-defined in the second print. CHAPTER 2. THE OPENMP MEMORY MODEL 5
C/C++ Example mem_model.2c #pragma omp parallel num_threads(2) if (omp_get_thread_num()==0) s-11 s-12 witeto tha data buftor that will bo ead S-13 S-14 s-15 /Flush data to thread 1 and strictly order the write to 819 relative t。 818 thread 1/ flag =1; /Flush flag to ensure that thread 1 sees the change S-22 5-23 #pragma c mp flush(flag) 1 S24 else if(omp_get_thread_num()==1) 9-25 s-26 /Loop until we see the update to the flag * s-27 pragma omp flush(flag,data) S-28 while (flag 1) S-29 S-30 #pragma omp flush(flag,data) S-31 S-32 /Values of flag and data are undefined * S-33 printf("flag=%d data=8d\n",flag,data); S-34 #pragma omp flush(flag,data) S-35 /Values data will be 42,value of flag S-36 still undefined * S-37 printf("flag=&d data=&d\n",flag,data); S-38 1 return 0; S-41 C/C++ 6 OpenMP Examples Version 4.0.2-March 2015
C / C++ 1 Example mem_model.2c S-1 #include <omp.h> S-2 #include <stdio.h> S-3 int main() S-4 { S-5 int data; S-6 int flag=0; S-7 #pragma omp parallel num_threads(2) S-8 { S-9 if (omp_get_thread_num()==0) S-10 { S-11 /* Write to the data buffer that will be S-12 read by thread */ S-13 data = 42; S-14 /* Flush data to thread 1 and strictly order S-15 the write to data S-16 relative to the write to the flag */ S-17 #pragma omp flush(flag, data) S-18 /* Set flag to release thread 1 */ S-19 flag = 1; S-20 /* Flush flag to ensure that thread 1 sees S-21 the change */ S-22 #pragma omp flush(flag) S-23 } S-24 else if(omp_get_thread_num()==1) S-25 { S-26 /* Loop until we see the update to the flag */ S-27 #pragma omp flush(flag, data) S-28 while (flag < 1) S-29 { S-30 #pragma omp flush(flag, data) S-31 } S-32 /* Values of flag and data are undefined */ S-33 printf("flag=%d data=%d\n", flag, data); S-34 #pragma omp flush(flag, data) S-35 /* Values data will be 42, value of flag S-36 still undefined */ S-37 printf("flag=%d data=%d\n", flag, data); S-38 } S-39 } S-40 return 0; S-41 } C / C++ 6 OpenMP Examples Version 4.0.2 - March 2015
Fortran Example mem_model.2f S-1 PROGRAM EXAMPLE INCLUDE "omp_lib.h"or USE OMP_LIB 4656745 INTEGER DATA INTEGER FLAG FLAG =0 SOMP PARALLEL NUM_THREADS(2) IF (OMP_GET_THREAD_NUM().EQ.0)THEN Write to the data buffer that will be read by thread 1 DATA= 92 Flush DATA to thread 1 and strictly order the write to DATA relative to the write to the FLAG SOMP FLUSH (FLAG,DATA) FLAG to release thread 1 to ensure that thread 1 sees the change * IF (OM FLUSH (FLAG) THREAD NUM().EQ.1)THEN che FLAG DO DATA) MP FLUSH (FLAG,DATA) ENDDO Values of FLAG and DATA a PRINT ISOMP FLUSH (FLAG, DATA) IValyes DATA vijl he 42,,m of PLAG still undefined t PRINT 'FLAG-',FLAG, !SOMP END PARALLEL END Fortran 234 The next example demonstrates why synchr onization is difficult to perform correctly through variables.Because the write(1)-flush(1)-flush(2)-read(2)sequence cannot be guaranteed in the example,the statements on thread 0 and thread 1 may execute in either order. CHAPTER 2.THE OPENMP MEMORY MODEL 7
Fortran 1 Example mem_model.2f S-1 PROGRAM EXAMPLE S-2 INCLUDE "omp_lib.h" ! or USE OMP_LIB S-3 INTEGER DATA S-4 INTEGER FLAG S-5 S-6 FLAG = 0 S-7 !$OMP PARALLEL NUM_THREADS(2) S-8 IF(OMP_GET_THREAD_NUM() .EQ. 0) THEN S-9 ! Write to the data buffer that will be read by thread 1 S-10 DATA = 42 S-11 ! Flush DATA to thread 1 and strictly order the write to DATA S-12 ! relative to the write to the FLAG S-13 !$OMP FLUSH(FLAG, DATA) S-14 ! Set FLAG to release thread 1 S-15 FLAG = 1; S-16 ! Flush FLAG to ensure that thread 1 sees the change */ S-17 !$OMP FLUSH(FLAG) S-18 ELSE IF(OMP_GET_THREAD_NUM() .EQ. 1) THEN S-19 ! Loop until we see the update to the FLAG S-20 !$OMP FLUSH(FLAG, DATA) S-21 DO WHILE(FLAG .LT. 1) S-22 !$OMP FLUSH(FLAG, DATA) S-23 ENDDO S-24 S-25 ! Values of FLAG and DATA are undefined S-26 PRINT *, ’FLAG=’, FLAG, ’ DATA=’, DATA S-27 !$OMP FLUSH(FLAG, DATA) S-28 S-29 !Values DATA will be 42, value of FLAG still undefined */ S-30 PRINT *, ’FLAG=’, FLAG, ’ DATA=’, DATA S-31 ENDIF S-32 !$OMP END PARALLEL S-33 END Fortran 2 The next example demonstrates why synchronization is difficult to perform correctly through 3 variables. Because the write(1)-flush(1)-flush(2)-read(2) sequence cannot be guaranteed in the 4 example, the statements on thread 0 and thread 1 may execute in either order. CHAPTER 2. THE OPENMP MEMORY MODEL 7
C/C++ Example mem_model.3c int flag=0; #pragma omp parallel num_threads(3) if(omp_get_thread_num()==0) s-11 /Set flag to release thread 1*/ s-12 S-13 omp atomic update S-14 15 /Flush of flag is implied by the atomic directive + 1 else if(omp_get_thread_num()==1) 8 /Loop until we see that flag reaches 1+/ prag na omp flush(flag) 9 while(flag 1) S-22 5-23 pragma omp flush(flag) 1 printf("Thread 1 awoken\n"); 862 /Set flag to release thread 2*/ -27 /Flush of flag is implied by the atomic directive 1 S31 else if(omp get thread num()==2) S-32 s-33 /Loop until we see that flag reaches 2/ S-34 #pragma omp flush(flag) s-35 while(flag 2) S-36 人 s-37 #pragma omp flush(flag) S-38 printf("Thread 2 awoken\n"); return 0; OpenMP Examples Version 4.0.2-March 2015
C / C++ 1 Example mem_model.3c S-1 #include <omp.h> S-2 #include <stdio.h> S-3 int main() S-4 { S-5 int flag=0; S-6 S-7 #pragma omp parallel num_threads(3) S-8 { S-9 if(omp_get_thread_num()==0) S-10 { S-11 /* Set flag to release thread 1 */ S-12 #pragma omp atomic update S-13 flag++; S-14 /* Flush of flag is implied by the atomic directive */ S-15 } S-16 else if(omp_get_thread_num()==1) S-17 { S-18 /* Loop until we see that flag reaches 1*/ S-19 #pragma omp flush(flag) S-20 while(flag < 1) S-21 { S-22 #pragma omp flush(flag) S-23 } S-24 printf("Thread 1 awoken\n"); S-25 S-26 /* Set flag to release thread 2 */ S-27 #pragma omp atomic update S-28 flag++; S-29 /* Flush of flag is implied by the atomic directive */ S-30 } S-31 else if(omp_get_thread_num()==2) S-32 { S-33 /* Loop until we see that flag reaches 2 */ S-34 #pragma omp flush(flag) S-35 while(flag < 2) S-36 { S-37 #pragma omp flush(flag) S-38 } S-39 printf("Thread 2 awoken\n"); S-40 } S-41 } S-42 return 0; S-43 } 8 OpenMP Examples Version 4.0.2 - March 2015
C/C++ Fortran Example mem_model.3f PROGRAM EXAMPLE INCLUD 1ib.h"!or USE OMP_LIB INTEGE ( NUM(3) NUM( ag 2n8a d at comic directive ELSE plied by the EN :FLAG reaches 1 第第第第 DO WHILE (FLAG .LT.1) ISOMP FLUSH (FLAG. DATA) ENDDO PRINT 'Thread 1 awoken' 8 Set FLAG to release thread 2 SOMP ATOMIC UPDATE FLAG=FLAG+1 !Flush of FLAG is implied by the atomic directive S-25 ELSE IF (OMP GET THREAD NUM().EQ.2)THEN S-26 Loop until we see that FLAG reaches 2 S-27 SOMP FLUSH(FLAG,DATA) S-28 DO WHILE(FIAG,工T,2) s-29 SOMP FLUSH (FLAG, DATA) S-30 ENDDO s31 福 PRINT,'Thread 2 awoken' ENDIF S-34 SOMP END PARALLEL S-35 END Fortran CHAPTER 2.THE OPENMP MEMORY MODEL 9
C / C++ Fortran 1 Example mem_model.3f S-1 PROGRAM EXAMPLE S-2 INCLUDE "omp_lib.h" ! or USE OMP_LIB S-3 INTEGER FLAG S-4 S-5 FLAG = 0 S-6 !$OMP PARALLEL NUM_THREADS(3) S-7 IF(OMP_GET_THREAD_NUM() .EQ. 0) THEN S-8 ! Set flag to release thread 1 S-9 !$OMP ATOMIC UPDATE S-10 FLAG = FLAG + 1 S-11 !Flush of FLAG is implied by the atomic directive S-12 ELSE IF(OMP_GET_THREAD_NUM() .EQ. 1) THEN S-13 ! Loop until we see that FLAG reaches 1 S-14 !$OMP FLUSH(FLAG, DATA) S-15 DO WHILE(FLAG .LT. 1) S-16 !$OMP FLUSH(FLAG, DATA) S-17 ENDDO S-18 S-19 PRINT *, ’Thread 1 awoken’ S-20 S-21 ! Set FLAG to release thread 2 S-22 !$OMP ATOMIC UPDATE S-23 FLAG = FLAG + 1 S-24 !Flush of FLAG is implied by the atomic directive S-25 ELSE IF(OMP_GET_THREAD_NUM() .EQ. 2) THEN S-26 ! Loop until we see that FLAG reaches 2 S-27 !$OMP FLUSH(FLAG, DATA) S-28 DO WHILE(FLAG .LT. 2) S-29 !$OMP FLUSH(FLAG, DATA) S-30 ENDDO S-31 S-32 PRINT *, ’Thread 2 awoken’ S-33 ENDIF S-34 !$OMP END PARALLEL S-35 END Fortran CHAPTER 2. THE OPENMP MEMORY MODEL 9