The FLUSH directive ensures that each thread has access to data generated by other threads. This directive is required because the compiler may keep values in processor registers if a program is optimized. The FLUSH directive ensures that the memory images that each thread views are consistent.
The FLUSH directive only takes effect if you specify the -qsmp compiler option.
You might be able to improve the performance of your program by using the FLUSH directive instead of the VOLATILE attribute. The VOLATILE attribute causes variables to be flushed after every update and before every use, while FLUSH causes variables to be written to or read from memory only when specified.
You can specify this directive anywhere in your code; however, if you specify it outside of the dynamic extent of a parallel region, it is ignored.
If you specify a variable_name_list, only the variables in that list are written to or read from memory (assuming that they have not been written or read already). All variables in the variable_name_list must be at the current scope and must be thread visible. Thread visible variables can be any of the following:
If you do not specify a variable_name_list, all thread visible variables are written to or read from memory.
When a thread encounters the FLUSH directive, it writes into memory the modifications to the affected variables. The thread also reads the latest copies of the variables from memory if it has local copies of those variables: for example, if it has copies of the variables in registers.
It is not mandatory for all threads in a team to use the FLUSH directive. However, to guarantee that all thread visible variables are current, any thread that modifies a thread visible variable should use the FLUSH directive to update the value of that variable in memory. If you do not use FLUSH or one of the directives that implies FLUSH (see below), the value of the variable might not be the most recent one.
Note that FLUSH is not atomic. You must FLUSH shared variables that are controlled by a shared lock variable with one directive and then FLUSH the lock variable with another. This guarantees that the shared variables are written before the lock variable.
The following directives imply a FLUSH directive unless you specify a NOWAIT clause for those directives to which it applies:
Example 1: In the following example, two threads perform calculations in parallel and are synchronized when the calculations are complete:
PROGRAM P INTEGER INSYNC(0:1), IAM !$OMP PARALLEL DEFAULT(PRIVATE) SHARED(INSYNC) IAM = OMP_GET_THREAD_NUM() INSYNC(IAM) = 0 !$OMP BARRIER CALL WORK !$OMP FLUSH(INSYNC) INSYNC(IAM) = 1 ! Each thread sets a flag ! once it has !$OMP FLUSH(INSYNC) ! completed its work. DO WHILE (INSYNC(1-IAM) .eq. 0) ! One thread waits for ! another to complete !$OMP FLUSH(INSYNC) ! its work. END DO !$OMP END PARALLEL END PROGRAM P SUBROUTINE WORK ! Each thread does indep- ! endent calculations. ! ... !$OMP FLUSH ! flush work variables ! before INSYNC ! is flushed. END SUBROUTINE WORK
Example 2: The following example is not valid, because it attempts to use FLUSH with a variable that is not thread visible:
FUNCTION F() INTEGER, AUTOMATIC :: i !$OMP FLUSH(I) END FUNCTION F