openmp常用指令(fortran版)(2)
1.!OMPDO/! OMP END DO
指令对使最近的do循环并行执行,将do循环分散到不同的线程,每个线程仅仅计算部分迭代,所有的线程之和完成所有的计算任务,换句话说,就是所有的线程合力去完成所有的循环;
program test
use omp_lib
!call omp_set_nested(.true.)
write(*,*) "线程数为:",omp_get_num_procs()
!$OMP PARALLEL
!$OMP DO
Do i=1,10
write(*,10) i,OMP_get_thread_num()
end do
!$OMP END DO
!$OMP END PARALLEL
10 FORMAT(1X,'i=',I3,' ThreadID=',I3)
End program
其中,OMP_get_thread_num()是omp_lib中的函数,返回当前线程的线程号,取值范围0到并行区域线程数-1,后续相关函数还有有相关介绍;本实验开了四个线程,结果如下:
可以看到i从1到10分别由不同的thread打印输出;
值得注意的是:因为是并行计算,一次迭代的输入是上一次的迭代的结果,这种情况就会在成不确定性结果,像下面的程序:
real(8) :: A(1000)
do i = 1, 999
A(i) = A(i+1)
End do
错误的原因是:在执行第i次迭代时,需要索引i+1处的未修改值。串行执行时毫无问题,但在并行计算时,不能获取到i+1处的未修改值。这种情况称为竞赛条件(racing condition):结果依赖于线程执行顺序和每颗处理器的速度。
2.!OMPSECTIONS/! OMP END SECTIONS
指令对允许给每个线程分派完全不同的任务,生成MPMD(Multiple Programs Multiple Data)执行模块。每段代码仅被一个线程执行一次,代码如下:
!$OMP PARALLEL
!$OMP SECTIONS
!$OMP SECTION
write(*,*)"hello" , OMP_get_thread_num()
!$OMP SECTION
write(*,*)"hi" , OMP_get_thread_num()
!$OMP SECTION
write(*,*)"Bye" , OMP_get_thread_num()
!$OMP END SECTIONS
!$OMP END PARALLEL
每段代码被唯一线程执行,以!
指令;或者以!$OMP END SECTIONS指令结束。可在当前指令对内定义任意数量的代码段,
但只有已经存在的线程才可以分派代码块。这意味着如果代码段的数量大于可用线程数,部
分线程将会串行执行不止一段代码。如果代码段的数量少于线程数,又将导致有效资源的低
效率使用。举例来说,如果由4线程执行5个代码段,在第四个线程执行第五个代码段时,另
外3个线程会被闲置。
最后的运行结果是:
3.!OMPSINGLE/! OMP END SINGLE
指令对包含的代码仅由其中一条线程执行,也就是最先到达!
示意图如下:
另外!
上一篇: sqoop的安装及简单使用