• openmp 循环并行化循环嵌套内部无法并行


     

    10.3.1.3 显式并行化抑制因素

    一般而言,如果您显式指导编译器对循环进行并行化,编译器就会执行。但也有例外情况-存在一些编译器不进行并行化的循环。

    下面是可检测到的主要抑制因素,这些抑制因素可以防止DO 循环进行显式并行化:

    • DO 循环嵌套在已并行化的另一 DO 循环内。

      该例外情况也适用于间接嵌套。如果显式并行化包含子例程调用的循环,那么,即使要求编译器并行化该子例程中的循环,这些循环在运行时也不会以并行方式运行。

    • 流控制语句允许跳出 DO 循环。

    • 循环的索引变量受副作用影响,例如被等价。

    通过使用 -vpara -loopinfo 进行编译,可以得到诊断消息,指出在显式并行化循环过程中编译器是否检测到问题。

    下表列出了编译器检测到的典型并行化问题:

    表 10–3 显式并行化问题

    问题 

    已并行化 

    警告消息 

    循环嵌套在并行化了的另一循环内。 

    否 

    否 

    循环在并行化循环体内调用的某个子例程中。 

    否 

    否 

    流控制语句允许跳出循环。 

    否 

    是 

    循环的索引变量受副作用影响。 

    是 

    否 

    循环中的某变量具有循环携带依赖性。 

    是 

    是 

    在循环中使用 I/O 语句-通常是不明智的,因为输出顺序无法预料。

    是 

    否 

    示例:嵌套循环:


          ...
    !$OMP PARALLEL DO
          do 900 i = 1, 1000      !  Parallelized (outer loop)
            do 200 j = 1, 1000    !  Not parallelized, no warning
                ...
    200   continue
    900      continue
          ...

    示例:子例程中已并行化的循环:


     program main
          ...
    !$OMP PARALLEL DO
          do 100 i = 1, 200      <-parallelized
            ...
            call calc (a, x)
            ...
    100      continue
          ...
    subroutine calc ( b, y )
          ...
    !$OMP PARALLEL DO
          do 1 m = 1, 1000       <-not parallelized
            ...
    1      continue
          return
          end

    在此例中,由于子例程本身是以并行方式运行的,所以子例程中的循环未被并行化。

    示例:跳出循环:


    !$omp parallel do
          do i = 1, 1000     ! <- Not parallelized, error issued
            ...
            if (a(i) .gt. min_threshold ) go to 20
            ...
          end do
    20      continue
          ...

    如果标记进行并行化的循环外有转跳,编译器会发出诊断错误。

    示例:循环中的某个变量具有循环携带依赖性:


    demo% cat vpfn.f
          real function fn (n,x,y,z)
          real y(*),x(*),z(*)
          s = 0.0
    !$omp parallel do private(i,s) shared(x,y,z)
          do  i = 1, n
              x(i) = s
              s = y(i)*z(i)
          enddo
          fn=x(10)
          return
          end
    demo% f95 -c -vpara -loopinfo -openmp -O4 vpfn.f
    "vpfn.f", line 5: Warning: the loop may have parallelization inhibiting reference
    "vpfn.f", line 5: PARALLELIZED, user pragma used

    在此,循环被并行化,但在警告中诊断出可能的循环携带依赖性。但要注意,编译器并不能诊断出所有循环依赖性。

    10.3.1.4 显式并行化时的 I/O

    在下列情况下,可以在并行执行的循环中执行 I/O:

    • 来自不同线程的输出相互交错(程序输出是非确定的),这一点并不重要。

    • 可以确保并行执行循环的安全性。

    示例:循环中有 I/O 语句


    !$OMP PARALLEL DO PRIVATE(k)
          do i = 1, 10     !  Parallelized
            k = i
            call show ( k )
          end do
          end
          subroutine show( j )
          write(6,1) j
    1      format(’Line number ’, i3, ’.’)
          end
    demo% f95 -openmp t13.f
    demo% setenv PARALLEL 4
    demo% a.out
    

    Line number 9.
    Line number 4.
    Line number 5.
    Line number 6.
    Line number 1.
    Line number 2.
    Line number 3.
    Line number 7.
    Line number 8.

    但递归的 I/O,即 I/O 语句包含对本身执行 I/O 的函数的调用,将会造成运行时错误。

  • 相关阅读:
    Profibus 接线
    如何正确使用Profibus插头以及终端电阻
    Java设计模式(3)——抽象工厂模式
    Java设计模式(2)——工厂方法模式
    Java设计模式(1)——简单工厂模式
    Oracle——控制事务
    Jackson-将对象转为Json字符串
    $.ajax
    Ajax——jQuery实现
    Ajax——三种数据传输格式
  • 原文地址:https://www.cnblogs.com/catkins/p/5270802.html
Copyright © 2020-2023  润新知