【发布时间】:2024-04-13 18:15:01
【问题描述】:
我在scicomp 上遇到了这个问题,其中涉及计算总和。在那里,您可以看到 c++ 和类似的 fortran 实现。有趣的是,我看到 fortran 版本快了大约 32%。
我想,我不确定他们的结果,并试图恢复这种情况。这是我运行的(非常轻微的)不同的代码:
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 标志的Ubuntu 12.04 LTS 机器上使用gcc 4.6.3 和clang 3.0 编译上述代码。这是我的时间安排:
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 时,我还可以看到fortran 代码比c++ 快大约相同的32%。但是,使用clang,我可以看到c++ 代码实际上运行速度快了大约19%。以下是我的问题:
- 为什么 g++ 生成的代码比 gfortran 慢?由于它们来自同一个编译器系列,这是否意味着(这个)fortran 代码可以简单地翻译成更快的代码? fortran vs c++ 通常是这种情况吗?
- 为什么
clang在这里做得这么好? llvm 编译器是否有 fortran 前端?如果有,那生成的代码会更快吗?
更新:
使用-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 的 -ffast-math 等选项可能会显着影响时间。
-
@NikolayViskov 我在所有编译器上明确使用的唯一标志是
-O3。 -
在我的机器上:clang
0.62(-ffast-math0.60), g++4.61.23(-ffast-math0.78), g++4.71.19(-ffast-math0.76) -
你真的需要输出吗?对我来说,删除条件和 ostream 输出将 C++ 版本的速度提高了十倍,这表明速度很慢是在不进行计算的情况下进行的。即使没有输出,Clang 仍然比 G++ 快得多,除非我使用
-std=c++11并且突然 Clang 变得非常慢。 -
@JonathanWakely:我的经验是,如果没有输出,gfortran 编译的代码实际上不会运行(恒定的 0.001 秒运行时间)。
标签: c++ gcc fortran llvm clang