如何使用OpenMP部分并行执行独立任务

时间:2017-06-30 14:46:46

标签: fortran openmp gfortran

我试图了解如何使用OpenMP部分。下面列出的程序是从其中一个llnl教程中提取的,解释说明:'简单程序演示不同的工作块将由不同的线程完成。

!!编译:gfortran -fopenmp -o omp_worksections omp_worksections.f90   !还需要:导出OMP_NUM_THREADS = 2(或3或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 DIRECTIVE中的NOWAIT子句,并从PARALLEL指令的shared子句中删除C,D无效。

我显然错过了这个难题的一些中心部分?

1 个答案:

答案 0 :(得分:1)

似乎当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.