私は合計を計算することを含むscicompでこの問題に遭遇しました。そこには、c++と同様のfortranの実装があります。興味深いことに、私はfortranバージョンが約32%速いことを見た。clang ++/g ++/gfortranの簡単なテストケース
私はその結果についてはわからないと思って、状況を再現しようとしました。私はすべてのUbuntu 12.04 LTS
マシン上gcc 4.6.3
とclang 3.0
を使用して上記のコードをコンパイル
C++
#include <iostream>
#include <complex>
#include <cmath>
#include <iomanip>
int main()
{
const double alpha = 1;
std::cout.precision(16);
std::complex<double> sum = 0;
const std::complex<double> a = std::complex<double>(1,1)/std::sqrt(2.);
for (unsigned int k=1; k<10000000; ++k)
{
sum += std::pow(a, k)*std::pow(k, -alpha);
if (k % 1000000 == 0)
std::cout << k << ' ' << sum << std::endl;
}
return 0;
}
FORTRAN
implicit none
integer, parameter :: dp = kind(0.d0)
complex(dp), parameter :: i_ = (0, 1)
real(dp) :: alpha = 1
complex(dp) :: s = 0
integer :: k
do k = 1, 10000000
s = s + ((i_+1)/sqrt(2._dp))**k * k**(-alpha)
if (modulo(k, 1000000) == 0) print *, k, s
end do
end
:ここで私は走った(非常にわずかに)異なるコードです-O3
フラグ。ここに私のタイミングです:
time ./a.out
のgfortran
real 0m1.538s
user 0m1.536s
sys 0m0.000s
G ++
real 0m2.225s
user 0m2.228s
sys 0m0.000s
打ち鳴らす
real 0m1.250s
user 0m1.244s
sys 0m0.004s
興味深いことに、gcc
を使用した場合、コードがc++
よりも約32%早くなっています。しかし、clang
を使用すると、c++
コードが実際には約19%速く実行されることがわかります。ここに私の質問があります:
- なぜg ++生成コードがgfortranよりも遅いのですか?同じコンパイラファミリのものなので、このFortranコードは単純に高速なコードに変換できますか?これは一般的にfortran vs C++の場合ですか?
clang
はなぜここでうまくいくのですか? llvmコンパイラ用のfortranフロントエンドはありますか?もしあれば、それによって生成されたコードはさらに速くなりますか?
UPDATE:-ffast-math -O3
オプションを使用
は、以下の結果を生成する:
のgfortran
real 0m1.515s
user 0m1.512s
sys 0m0.000s
G ++
real 0m1.478s
user 0m1.476s
sys 0m0.000s
打ち鳴らす
real 0m1.253s
user 0m1.252s
sys 0m0.000s
NPW g++
バージョンはgfortran
早く実行されていると、まだclang
は両方よりも高速です。上記のオプションに-fcx-fortran-rules
を追加しても、結果は大きく変わりません。
コンパイルに使用するコンパイラオプションを指定してください。 gccの-phast-mathのようなオプションは、タイミングに大きな影響を与える可能性があります。 –
@ NikolayViskov私が明示的に使用する唯一のフラグは、すべてのコンパイラで '-O3'です。 – GradGuy
私のマシン上で:clang '0.62'(-ffast-math' 0.60')、g ++ 4.6 '1.23'(-ffast-math' 0.78')、g ++ 4.7 '1.19'(-ffast-math' 0.76 ') – leemes