并行计算

Using threadprivate and private

2023-11-30  本文已影响0人  loughsjtu

The THREADPRIVATE directive is used to make global file scope variables (C/C++) or common blocks (Fortran) local and persistent to a thread through the execution of multiple parallel regions.

The PRIVATE clause declares variables in its list to be private to each thread.

When developing with openMP, please make sure to keep the declaration of threadprivate/private variables be consistent during the execution. You should not using inconsistent declaration in different subroutines inside a same parallel block.

An example different combinations are attached for demonstration.

In the attached example, the declaration is correct for:

common block /MSP/;

variable SP0 in common block /SP/;

variable SP2 in common block /SP2/.

While the declaration is incorrect for:

common block /MP/;

variable SP1 in common block /SP/.

As we can see in the out.txt, we can always get consistent results for MSP1, SP0 and SP2 in main routine and subroutine for every threads.

But for SP1 and SP2, it is different in main routine and subroutine.

Useful links:

https://hpc-tutorials.llnl.gov/openmp/threadprivate_directive/

https://hpc-tutorials.llnl.gov/openmp/private_clause/

ifort -c main_threadprivate.f90 /Qauto /Qopenmp

ifort -c sub_thread.f90 /Qauto /Qopenmp

ifort -o threadprivate_test.exe main_threadprivate.obj sub_thread.obj

threadprivate_test.exe >out.txt

==================main_threadprivate.f90 ==========================

PROGRAM MAIN

! A DEMONSTRATION PROGRAM TO SHOW CORRECT AND INCORRECT WAY TO DECLARE

! THREADPRIVATE AND PRIVATE VARIABLES BY openMP.

!

    IMPLICIT NONE

    INTEGER MSP1,MP1,SP0,SP1,SP2,TTID,OMP_GET_THREAD_NUM,OMP_SET_NUM_THREADS

    !      MSP: MAIN+SUBROUTINE PRIVATE

    COMMON /MSP/MSP1

    COMMON /MP/MP1

    COMMON /SP/SP0,SP1

    COMMON /SP2/SP2

!$OMP THREADPRIVATE(/MSP/,/MP/)   

!

!INITIALIZATION

    MSP1 = 10

    MP1  = 20

    SP0  = 30

    SP1  = 31

    SP2  = 32

!

    TTID = OMP_GET_THREAD_NUM()

!$OMP CRITICAL

    WRITE(*,*) 'INITIAL VALUE IN MAIN MSP1=',MSP1, 'TTID=',TTID

    WRITE(*,*) 'INITIAL VALUE IN MAIN  MP1=', MP1, 'TTID=',TTID

    WRITE(*,*) 'INITIAL VALUE IN MAIN, SP0=', SP0, 'TTID=',TTID

    WRITE(*,*) 'INITIAL VALUE IN MAIN, SP1=', SP1, 'TTID=',TTID

    WRITE(*,*) 'INITIAL VALUE IN MAIN, SP2=', SP2, 'TTID=',TTID

!$OMP END CRITICAL

!

    WRITE(*,*) 'PARALLEL BEGINS'

!$OMP PARALLEL COPYIN(/MSP/) PRIVATE(SP1) FIRSTPRIVATE(SP2)

!

!$OMP CRITICAL

    TTID = OMP_GET_THREAD_NUM()

    MSP1=MSP1+TTID

    MP1=MP1+TTID

    SP0=SP0+TTID

    SP1=SP1+TTID

    SP2=SP2+TTID

    WRITE(*,*) 'MAIN AFTER PARALLEL, MSP1=',MSP1,'TTID=',TTID

    WRITE(*,*) 'MAIN AFTER PARALLEL,  MP1=',MP1, 'TTID=',TTID

    WRITE(*,*) 'MAIN AFTER PARALLEL,  SP0=',SP0, 'TTID=',TTID

    WRITE(*,*) 'MAIN AFTER PARALLEL,  SP1=',SP1, 'TTID=',TTID

    WRITE(*,*) 'MAIN AFTER PARALLEL,  SP2=',SP2, 'TTID=',TTID

      CALL SUB_THREAD(SP2)

!$OMP END CRITICAL

!

!$OMP END PARALLEL

STOP

END

==============sub_thread.f90================================

SUBROUTINE SUB_THREAD(SP2)

!

    IMPLICIT NONE   

    INTEGER MSP1,MP1,SP0,SP1,SP2,TTID,OMP_GET_THREAD_NUM

    !MSP MAIN+SUBROUTINE PRIVATE

    COMMON /MSP/MSP1

    COMMON /MP/MP1

    COMMON /SP/SP0,SP1

!$OMP THREADPRIVATE(/MSP/)

!

    TTID = OMP_GET_THREAD_NUM()

    WRITE(*,*) 'SUB_THREAD, MSP1=',MSP1,'TTID=',TTID

    WRITE(*,*) 'SUB_THREAD,  MP1=',MP1, 'TTID=',TTID

    WRITE(*,*) 'SUB_THREAD,  SP0=',SP0, 'TTID=',TTID

    WRITE(*,*) 'SUB_THREAD,  SP1=',SP1, 'TTID=',TTID

    WRITE(*,*) 'SUB_THREAD,  SP2=',SP2, 'TTID=',TTID

    WRITE(*,*) '                          '

RETURN

END

=====================out.txt===================================

INITIAL VALUE IN MAIN MSP1= 10 TTID= 0

INITIAL VALUE IN MAIN  MP1=          20 TTID=          0

INITIAL VALUE IN MAIN, SP0=          30 TTID=          0

INITIAL VALUE IN MAIN, SP1=          31 TTID=          0

INITIAL VALUE IN MAIN, SP2=          32 TTID=          0

PARALLEL BEGINS

MAIN AFTER PARALLEL, MSP1=          10 TTID=          0

MAIN AFTER PARALLEL,  MP1=          20 TTID=          0

MAIN AFTER PARALLEL,  SP0=          30 TTID=          0

MAIN AFTER PARALLEL,  SP1=          0 TTID=          0

MAIN AFTER PARALLEL,  SP2=          32 TTID=          0

SUB_THREAD, MSP1=          10 TTID=          0

SUB_THREAD,  MP1=          20 TTID=          0

SUB_THREAD,  SP0=          30 TTID=          0

SUB_THREAD,  SP1=          31 TTID=          0

SUB_THREAD,  SP2=          32 TTID=          0

MAIN AFTER PARALLEL, MSP1=          16 TTID=          6

MAIN AFTER PARALLEL,  MP1=          6 TTID=          6

MAIN AFTER PARALLEL,  SP0=          36 TTID=          6

MAIN AFTER PARALLEL,  SP1=          6 TTID=          6

MAIN AFTER PARALLEL,  SP2=          38 TTID=          6

SUB_THREAD, MSP1=          16 TTID=          6

SUB_THREAD,  MP1=          20 TTID=          6

SUB_THREAD,  SP0=          36 TTID=          6

SUB_THREAD,  SP1=          31 TTID=          6

SUB_THREAD,  SP2=          38 TTID=          6

MAIN AFTER PARALLEL, MSP1=          12 TTID=          2

MAIN AFTER PARALLEL,  MP1=          2 TTID=          2

MAIN AFTER PARALLEL,  SP0=          38 TTID=          2

MAIN AFTER PARALLEL,  SP1=          2 TTID=          2

MAIN AFTER PARALLEL,  SP2=          34 TTID=          2

SUB_THREAD, MSP1=          12 TTID=          2

SUB_THREAD,  MP1=          20 TTID=          2

SUB_THREAD,  SP0=          38 TTID=          2

SUB_THREAD,  SP1=          31 TTID=          2

SUB_THREAD,  SP2=          34 TTID=          2

MAIN AFTER PARALLEL, MSP1=          17 TTID=          7

MAIN AFTER PARALLEL,  MP1=          7 TTID=          7

MAIN AFTER PARALLEL,  SP0=          45 TTID=          7

MAIN AFTER PARALLEL,  SP1=          7 TTID=          7

MAIN AFTER PARALLEL,  SP2=          39 TTID=          7

SUB_THREAD, MSP1=          17 TTID=          7

SUB_THREAD,  MP1=          20 TTID=          7

SUB_THREAD,  SP0=          45 TTID=          7

SUB_THREAD,  SP1=          31 TTID=          7

SUB_THREAD,  SP2=          39 TTID=          7

MAIN AFTER PARALLEL, MSP1=          14 TTID=          4

MAIN AFTER PARALLEL,  MP1=          4 TTID=          4

MAIN AFTER PARALLEL,  SP0=          49 TTID=          4

MAIN AFTER PARALLEL,  SP1=          4 TTID=          4

MAIN AFTER PARALLEL,  SP2=          36 TTID=          4

SUB_THREAD, MSP1=          14 TTID=          4

SUB_THREAD,  MP1=          20 TTID=          4

SUB_THREAD,  SP0=          49 TTID=          4

SUB_THREAD,  SP1=          31 TTID=          4

SUB_THREAD,  SP2=          36 TTID=          4

MAIN AFTER PARALLEL, MSP1=          13 TTID=          3

MAIN AFTER PARALLEL,  MP1=          3 TTID=          3

MAIN AFTER PARALLEL,  SP0=          52 TTID=          3

MAIN AFTER PARALLEL,  SP1=          3 TTID=          3

MAIN AFTER PARALLEL,  SP2=          35 TTID=          3

SUB_THREAD, MSP1=          13 TTID=          3

SUB_THREAD,  MP1=          20 TTID=          3

SUB_THREAD,  SP0=          52 TTID=          3

SUB_THREAD,  SP1=          31 TTID=          3

SUB_THREAD,  SP2=          35 TTID=          3

MAIN AFTER PARALLEL, MSP1=          11 TTID=          1

MAIN AFTER PARALLEL,  MP1=          1 TTID=          1

MAIN AFTER PARALLEL,  SP0=          53 TTID=          1

MAIN AFTER PARALLEL,  SP1=          1 TTID=          1

MAIN AFTER PARALLEL,  SP2=          33 TTID=          1

SUB_THREAD, MSP1=          11 TTID=          1

SUB_THREAD,  MP1=          20 TTID=          1

SUB_THREAD,  SP0=          53 TTID=          1

SUB_THREAD,  SP1=          31 TTID=          1

SUB_THREAD,  SP2=          33 TTID=          1

MAIN AFTER PARALLEL, MSP1=          15 TTID=          5

MAIN AFTER PARALLEL,  MP1=          5 TTID=          5

MAIN AFTER PARALLEL,  SP0=          58 TTID=          5

MAIN AFTER PARALLEL,  SP1=          5 TTID=          5

MAIN AFTER PARALLEL,  SP2=          37 TTID=          5

SUB_THREAD, MSP1=          15 TTID=          5

SUB_THREAD,  MP1=          20 TTID=          5

SUB_THREAD,  SP0=          58 TTID=          5

SUB_THREAD,  SP1=          31 TTID=          5

SUB_THREAD,  SP2=          37 TTID=          5

======================END=============================

上一篇 下一篇

猜你喜欢

热点阅读