いくつかのFortranコードをcに移植していたとき、ifortでコンパイルされたFortranプログラム(Intel Fortranコンパイラ)とgccでコンパイルされたcプログラムの間の実行時間の不一致のほとんどが、三角関数の評価に起因していることに驚きました(sin
、cos
)。サインやコサインのような関数がマイクロプロセッサ内のマイクロコードに実装されているというこの答えが説明していることを信じていたので、私は驚きました。
問題をより明確に特定するために、Fortranで小さなテストプログラムを作成しました
program ftest
implicit none
real(8) :: x
integer :: i
x = 0d0
do i = 1, 10000000
x = cos (2d0 * x)
end do
write (*,*) x
end program ftest
プロセッサintel Q6600
と3.6.9-1-ARCH x86_64 Linux
私はifort version 12.1.0
$ ifort -o ftest ftest.f90
$ time ./ftest
-0.211417093282753
real 0m0.280s
user 0m0.273s
sys 0m0.003s
gcc version 4.7.2
私が得る間
$ gfortran -o ftest ftest.f90
$ time ./ftest
0.16184945593939115
real 0m2.148s
user 0m2.090s
sys 0m0.003s
これはほぼ10倍の違いです!cos
のgcc実装は、おそらくIntel実装で行われるのと同様の方法で、マイクロプロセッサ実装のラッパーであると私はまだ信じることができますか?これが本当なら、ボトルネックはどこにありますか?
編集
コメントによると、有効化された最適化はパフォーマンスを改善するはずです。私の意見では、最適化はライブラリ関数に影響を与えません...これは、重要なプログラムでそれらを使用しないという意味ではありません。ただし、ここに2つの追加のベンチマークがあります(現在は自宅のコンピューターにありますintel core2
)
$ gfortran -o ftest ftest.f90
$ time ./ftest
0.16184945593939115
real 0m2.993s
user 0m2.986s
sys 0m0.000s
と
$ gfortran -Ofast -march=native -o ftest ftest.f90
$ time ./ftest
0.16184945593939115
real 0m2.967s
user 0m2.960s
sys 0m0.003s
あなた(コメンテーター)はどの特定の最適化を念頭に置いていましたか?そして、各反復が前の反復の結果に依存するこの特定の例で、コンパイラはどのようにマルチコアプロセッサを活用できますか?
編集2
DanielFisherとIlmariKaronenのベンチマークテストでは、問題はgccの特定のバージョン(4.7.2)に関連している可能性があり、コンピューターで使用している特定のビルド(Arch x86_64 Linux)に関連している可能性があると考えました。そこで、intel core i7
ボックスでdebian x86_64 Linux
テストgcc version 4.4.5
を繰り返しました。ifort version 12.1.0
$ gfortran -O3 -o ftest ftest.f90
$ time ./ftest
0.16184945593939115
real 0m0.272s
user 0m0.268s
sys 0m0.004s
と
$ ifort -O3 -o ftest ftest.f90
$ time ./ftest
-0.211417093282753
real 0m0.178s
user 0m0.176s
sys 0m0.004s
私にとって、これは非常に許容できるパフォーマンスの違いであり、この質問をすることは決してありません。この問題については、ArchLinuxフォーラムで質問する必要があるようです。
しかし、全体の説明はまだ大歓迎です。