Fortran+ OpenMP 学习之,块并行和DO并行两种循环的比较

参考自Fortran+ OpenMP实现实例

下面的代码展示了分别使用 串行计算,块并行(OMP sections)和DO并行(OMP Do)计算速度的差异。

代码的功能是最两个矩阵进行初始化(赋初值)。第一个方法是传统的串行计算;第二个方法是使用!OMP section语句,将任务分成两个块section,然后同时运行;第三个方法是使用DO并行,各步循环同时执行。

最终效果,是使用OMP DO 并行的计算速度最快

 

jlz@dell:~$ ifort -qopenmp omptest.f90 && ./a.out
 开始进行串行计算
 The value of k after serial computing is:    2000000.00000000     
 The time wasted on serial computing is:           83
 
 
 开始进行第一类串行计算—SECTIONS
 The value of k after parallel computing is:    1000000.00000000      
 , and it comes from the thread of            0
 The value of k after parallel computing is:    1000000.00000000      
 , and it comes from the thread of            1
 The time wasted on the first class parallel computing is:           66
 
 
 开始进行第二类并行计算—DO
 The time wasted on the first class parallel computing is:           10

  

  

 

 代码(来自 B325帅猫-量子前沿技术研究所 的CSDN 博客https://blog.csdn.net/dengm155/article/details/78837408?utm_source=copy )

    PROGRAM parallel_01

    USE omp_lib
    IMPLICIT NONE

    INTEGER :: i,j
    INTEGER(4) :: time_begin, time_end, time_rate
    REAL, DIMENSION(1:1000,1:1000) :: f, g
    REAL(8) :: k

    WRITE(*,*) '开始进行串行计算'
    !>@ 1、通过串行计算获得两个矩阵的初始化计算
    CALL system_clock(time_begin,time_rate)
    DO i = 1, 1000
        DO j = 1, 1000
            f(i,j) = i*j
            k = k + 1
        END DO
    END DO

    DO i = 1, 1000
        DO j = 1, 1000
            g(i,j) = i*j + 1
            k = k + 1
        END DO
    END DO

    CALL system_clock(time_end,time_rate)
    WRITE(*,*) 'The value of k after serial computing is: ', k
    WRITE(*,*) 'The time wasted on serial computing is: ',(time_end -time_begin)
    WRITE(*,*)
    WRITE(*,*)
    WRITE(*,*) '开始进行第一类串行计算—SECTIONS'

    !>@ 2、通过块并行计算获得两个矩阵的初始化计算
    k = 0 ! 重新初始化k的值
    CALL system_clock(time_begin,time_rate)
    CALL omp_set_num_threads(2)
    !$omp parallel
    !$omp sections private(i,j,k)
    !$omp section
    DO i = 1, 1000
        DO j = 1, 1000
            f(i,j) = i*j
            k = k + 1
        END DO
    END DO
    WRITE(*,*) 'The value of k after parallel computing is: ', k,', and it comes from the thread of ',omp_get_thread_num()

    !$omp section
    DO i = 1, 1000
        DO j = 1, 1000
            g(i,j) = i*j + 1
            k = k + 1
        END DO
    END DO
    WRITE(*,*) 'The value of k after parallel computing is: ', k,', and it comes from the thread of ',omp_get_thread_num()
    !$omp end sections
    !$omp end parallel

    CALL system_clock(time_end,time_rate)
    WRITE(*,*) 'The time wasted on the first class parallel computing is: ',(time_end -time_begin)
    WRITE(*,*)
    WRITE(*,*)
    WRITE(*,*) '开始进行第二类并行计算—DO'

    !>@ 3、通过DO循环实现两个矩阵的初始化计算
    k = 0 ! 重新初始化k的值
    CALL system_clock(time_begin,time_rate)
    !$omp parallel private(k,j,i)
    !$omp do
    DO i = 1, 1000
        DO j = 1, 1000
            f(i,j) = i*j
            k = k + 1
            ! 去掉注释后,可显示每一次循环所在的线程ID
            !WRITE(*,*) 'The value of k after parallel computing is: ', k,', and it comes from the thread of ',omp_get_thread_num()
        END DO
    END DO
    !$omp end do
    !$omp end parallel

    !$omp parallel private(k,j,i)
    !$omp do
    DO i = 1, 1000
        DO j = 1, 1000
            g(i,j) = i*j
            k = k + 1
            !WRITE(*,*) 'The value of k after parallel computing is: ', k,', and it comes from the thread of ',omp_get_thread_num()
        END DO
    END DO
    !$omp end do
    !$omp end parallel
    CALL system_clock(time_end,time_rate)
    WRITE(*,*) 'The time wasted on the first class parallel computing is: ',(time_end -time_begin)
    END PROGRAM

 

posted @ 2020-10-12 21:50  chinagod  阅读(564)  评论(0)    收藏  举报