Fortran+ OpenMP 学习之,块并行和DO并行两种循环的比较
下面的代码展示了分别使用 串行计算,块并行(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
浙公网安备 33010602011771号