30

いくつかのFortranコードをcに移植していたとき、ifortでコンパイルされたFortranプログラム(Intel Fortranコンパイラ)とgccでコンパイルされたcプログラムの間の実行時間の不一致のほとんどが、三角関数の評価に起因していることに驚きました(sincos)。サインやコサインのような関数がマイクロプロセッサ内のマイクロコードに実装されているというこの答えが説明していることを信じていたので、私は驚きました。

問題をより明確に特定するために、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 Q66003.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フォーラムで質問する必要があるようです。

しかし、全体の説明はまだ大歓迎です。

4

1 に答える 1

17

これのほとんどは、数学ライブラリの違いによるものです。考慮すべきいくつかのポイント:

  • はい、x87ユニットを搭載したx86プロセッサにはfsinおよびfcos命令があります。ただし、これらはマイクロコードで実装されており、純粋なソフトウェア実装よりも高速でなければならない特別な理由はありません。
  • GCCには独自の数学ライブラリはありませんが、提供されているシステムを使用します。Linuxでは、これは通常glibcによって提供されます。
  • 32ビットx86glibcはfsin/fcosを使用します。
  • x86_64 glibcは、SSE2ユニットを使用したソフトウェア実装を使用します。長い間、これはx87命令を使用した32ビットのglibcバージョンよりもはるかに低速でした。ただし、(やや最近)改善が行われたため、使用しているglibcのバージョンによっては、状況が以前ほど悪くない場合があります。
  • インテル®コンパイラー・スイートは、非常に高速な数学ライブラリー(libimf)に恵まれています。さらに、ベクトル化された超越数学関数が含まれているため、これらの関数を使用してループをさらに高速化できることがよくあります。
于 2012-12-15T16:10:05.663 に答える