如何使用 OpenMP 部分并行执行独立任务
How to use OpenMP sections to perform independent tasks in parallel
我正在尝试了解如何使用 OpenMP 部分。下面列出的程序是从其中一个 llnl 教程中提取的,解释说明:'Simple program demonstrating that different blocks of work will be done by different threads'.
!!编译:gfortran -fopenmp -o omp_worksections omp_worksections.f90
!!还需要:export OMP_NUM_THREADS=2 (or 3 or 4)
PROGRAM WORKSECTIONS
INTEGER N, I, NTHREADS, TID, OMP_GET_NUM_THREADS,OMP_GET_THREAD_NUM
PARAMETER (N=1000)
REAL A(N), B(N), C(N), D(N)
! Some initializations
DO I = 1, N
A(I) = I * 1.5
B(I) = I + 22.35
C(N) = 0.0
D(N) = 0.0
ENDDO
!$OMP PARALLEL SHARED(A,B,C,D,NTHREADS), PRIVATE(I,TID)
TID = OMP_GET_THREAD_NUM()
IF (TID .EQ. 0) THEN
NTHREADS = OMP_GET_NUM_THREADS()
PRINT *, 'Number of threads =', NTHREADS
END IF
PRINT *, 'Thread',TID,' starting...'
!$OMP SECTIONS
!$OMP SECTION
PRINT *, 'Thread',TID,' doing section 1'
DO I = 1, N
C(I) = A(I) + B(I)
if (i.lt.10) then
WRITE(*,100) TID,I,C(I)
end if
100 FORMAT(' Thread',I2,': C(',I2,')=',F8.2)
ENDDO
!$OMP SECTION
PRINT *, 'Thread',TID,' doing section 2'
DO I = 1, N
if (i.lt.10) then
D(I) = A(I) * B(I)
WRITE(*,200) TID,I,D(I)
200 FORMAT(' Thread',I2,': D(',I2,')=',F8.2)
endif
ENDDO
!$OMP END SECTIONS NOWAIT
PRINT *, 'Thread',TID,' done.'
!$OMP END PARALLEL
END PROGRAM WORKSECTIONS
当我编译运行时,结果是:
Number of threads = 2
Thread 0 starting...
Thread 0 doing section 1
Thread 0: C( 1)= 24.85
Thread 0: C( 2)= 27.35
Thread 0: C( 3)= 29.85
Thread 0: C( 4)= 32.35
Thread 0: C( 5)= 34.85
Thread 0: C( 6)= 37.35
Thread 0: C( 7)= 39.85
Thread 0: C( 8)= 42.35
Thread 0: C( 9)= 44.85
Thread 1 starting...
Thread 0 doing section 2
Thread 0: D( 1)= 35.03
Thread 0: D( 2)= 73.05
Thread 0: D( 3)= 114.08
Thread 0: D( 4)= 158.10
Thread 0: D( 5)= 205.12
Thread 0: D( 6)= 255.15
Thread 0: D( 7)= 308.18
Thread 0: D( 8)= 364.20
Thread 0: D( 9)= 423.23
Thread 0 done.
Thread 1 done.
似乎线程 0 执行第 1 部分和第 2 部分?我期待任一部分的印刷品与一个线程执行第 1 节和另一个线程交织在第 2 节中。
我尝试删除 END SECTIONS 指令中的 NOWAIT 子句,并从 PARALLEL 指令中的共享子句中删除 C,D,但均无济于事。
我显然漏掉了拼图的核心部分?
看起来,当 OpenMP 运行时库为第二部分寻找空闲线程时,它发现线程 0 再次空闲,因为第一部分中要做的工作太少。所以它再次将工作分配给线程 0。
试试更大的 n
,比如 100000:
Number of threads = 2
Thread 0 starting...
Thread 0 doing section 1
Thread 0: C( 1)= 24.85
Thread 0: C( 2)= 27.35
Thread 0: C( 3)= 29.85
Thread 0: C( 4)= 32.35
Thread 0: C( 5)= 34.85
Thread 1 starting...
Thread 1 doing section 2
Thread 1: D( 1)= 35.03
Thread 1: D( 2)= 73.05
Thread 1: D( 3)= 114.08
Thread 1: D( 4)= 158.10
Thread 1: D( 5)= 205.12
Thread 1: D( 6)= 255.15
Thread 1: D( 7)= 308.18
Thread 1: D( 8)= 364.20
Thread 1: D( 9)= 423.23
Thread 0: C( 6)= 37.35
Thread 0: C( 7)= 39.85
Thread 0: C( 8)= 42.35
Thread 0: C( 9)= 44.85
Thread 1 done.
Thread 0 done.
我正在尝试了解如何使用 OpenMP 部分。下面列出的程序是从其中一个 llnl 教程中提取的,解释说明:'Simple program demonstrating that different blocks of work will be done by different threads'.
!!编译:gfortran -fopenmp -o omp_worksections omp_worksections.f90 !!还需要:export OMP_NUM_THREADS=2 (or 3 or 4)
PROGRAM WORKSECTIONS
INTEGER N, I, NTHREADS, TID, OMP_GET_NUM_THREADS,OMP_GET_THREAD_NUM
PARAMETER (N=1000)
REAL A(N), B(N), C(N), D(N)
! Some initializations
DO I = 1, N
A(I) = I * 1.5
B(I) = I + 22.35
C(N) = 0.0
D(N) = 0.0
ENDDO
!$OMP PARALLEL SHARED(A,B,C,D,NTHREADS), PRIVATE(I,TID)
TID = OMP_GET_THREAD_NUM()
IF (TID .EQ. 0) THEN
NTHREADS = OMP_GET_NUM_THREADS()
PRINT *, 'Number of threads =', NTHREADS
END IF
PRINT *, 'Thread',TID,' starting...'
!$OMP SECTIONS
!$OMP SECTION
PRINT *, 'Thread',TID,' doing section 1'
DO I = 1, N
C(I) = A(I) + B(I)
if (i.lt.10) then
WRITE(*,100) TID,I,C(I)
end if
100 FORMAT(' Thread',I2,': C(',I2,')=',F8.2)
ENDDO
!$OMP SECTION
PRINT *, 'Thread',TID,' doing section 2'
DO I = 1, N
if (i.lt.10) then
D(I) = A(I) * B(I)
WRITE(*,200) TID,I,D(I)
200 FORMAT(' Thread',I2,': D(',I2,')=',F8.2)
endif
ENDDO
!$OMP END SECTIONS NOWAIT
PRINT *, 'Thread',TID,' done.'
!$OMP END PARALLEL
END PROGRAM WORKSECTIONS
当我编译运行时,结果是:
Number of threads = 2
Thread 0 starting...
Thread 0 doing section 1
Thread 0: C( 1)= 24.85
Thread 0: C( 2)= 27.35
Thread 0: C( 3)= 29.85
Thread 0: C( 4)= 32.35
Thread 0: C( 5)= 34.85
Thread 0: C( 6)= 37.35
Thread 0: C( 7)= 39.85
Thread 0: C( 8)= 42.35
Thread 0: C( 9)= 44.85
Thread 1 starting...
Thread 0 doing section 2
Thread 0: D( 1)= 35.03
Thread 0: D( 2)= 73.05
Thread 0: D( 3)= 114.08
Thread 0: D( 4)= 158.10
Thread 0: D( 5)= 205.12
Thread 0: D( 6)= 255.15
Thread 0: D( 7)= 308.18
Thread 0: D( 8)= 364.20
Thread 0: D( 9)= 423.23
Thread 0 done.
Thread 1 done.
似乎线程 0 执行第 1 部分和第 2 部分?我期待任一部分的印刷品与一个线程执行第 1 节和另一个线程交织在第 2 节中。
我尝试删除 END SECTIONS 指令中的 NOWAIT 子句,并从 PARALLEL 指令中的共享子句中删除 C,D,但均无济于事。
我显然漏掉了拼图的核心部分?
看起来,当 OpenMP 运行时库为第二部分寻找空闲线程时,它发现线程 0 再次空闲,因为第一部分中要做的工作太少。所以它再次将工作分配给线程 0。
试试更大的 n
,比如 100000:
Number of threads = 2
Thread 0 starting...
Thread 0 doing section 1
Thread 0: C( 1)= 24.85
Thread 0: C( 2)= 27.35
Thread 0: C( 3)= 29.85
Thread 0: C( 4)= 32.35
Thread 0: C( 5)= 34.85
Thread 1 starting...
Thread 1 doing section 2
Thread 1: D( 1)= 35.03
Thread 1: D( 2)= 73.05
Thread 1: D( 3)= 114.08
Thread 1: D( 4)= 158.10
Thread 1: D( 5)= 205.12
Thread 1: D( 6)= 255.15
Thread 1: D( 7)= 308.18
Thread 1: D( 8)= 364.20
Thread 1: D( 9)= 423.23
Thread 0: C( 6)= 37.35
Thread 0: C( 7)= 39.85
Thread 0: C( 8)= 42.35
Thread 0: C( 9)= 44.85
Thread 1 done.
Thread 0 done.