3

Fortran で関数ポインタを使用することは可能ですか? 現在、次のような行を含むコードがあります。

subroutine flag(iflag,a,b)

integer n, a, b, ii, iflag

do ii = 1, n
     if (iflag.eq.0) a+b
     else a-b  
end do    

return
end

変数 "n" は非常に大きな値を持っているため、このコードを実行するには、"if" コマンドで多くの時間を無駄にしているように感じます。コードで次のようなことを行うように、関数ポインターのようなものを書くことは可能ですか (それが何を意味するのかわかりません)。

subroutine flag(iflag,a,b)

*depending on the iflag the subroutine flag is automatically 
precompiled to call either flag_plus or flag_minus*     

return
end

subroutine flag_plus(a,b)

integer n, a, b, ii

do ii = 1, n
     a+b
end do    

return
end

subroutine flag_minus(a,b)

integer n, a, b, ii

do ii = 1, n
     a-b  
end do    

return
end

可能であれば、「if」ループを回避することで多くの時間を節約できます。このようなことはリモートで可能ですか?

4

1 に答える 1

8

Fortran 77 では、関数ポインターの限定されたバリアントを持つことができます。つまり、プロシージャーの名前を引数として別のプロシージャー (本質的に関数ポインター) に渡すことができます。ただし、プロシージャのアドレスを含む変数を使用して、その変数を「呼び出す」ことはできません。

Fortran 2003 以降、プロシージャ ポインター変数は言語の一部です。

そうは言っても、あなたの例の問題は、次のような方法でさらに簡単に解決できると思います


if (iflag == 0) then  ! Why is iflag not of type logical?
  do ii = 1, n
    a + b
  end do
else
  do ii = 1, n
    a - b
  end do
end if

プロファイルを作成して、効果があるかどうかも確認してください。最新の CPU にはかなり優れた分岐予測子があり、ループ全体で変更されない分岐テストは、ほぼ最良のシナリオです (経験則: 予測された分岐はほぼフリーです)。一体、コンパイラは上記の種類の最適化を行うことさえできるかもしれません..

于 2013-05-21T10:27:05.220 に答える