这个主题可能已被讨论了数百次。我没有试图要求 任何语言都更糟或更好。我只是想学习如何加速我的C代码。 所以这里有两个代码来计算Pi。
第一个是Fortran90:
program calcpi
implicit none
integer :: i
real*8 :: pi
pi=0.0
do i = 0,1000000000
pi = pi + 1.0/(4.0*i+1.0)
pi = pi - 1.0/(4.0*i+3.0)
end do
pi = pi * 4.0
write(*,*) pi
end program calcpi
第二个是C:
#include<stdio.h>
#define STEPCOUNTER 1000000001
int main(int argc, char * argv[])
{
long i;
double pi=0;
#pragma omp parallel for reduction(+: pi)
for ( i=0 ; i < STEPCOUNTER; i++){
/*pi/4=1/11/3+1/51/7+...
To avoid the need to continually change
the sign (s=1; in each step s=s*-1 ),
we add two elements at the same time.*/
pi+=1.0/(i*4.0+1.0);
pi-=1.0/(i*4.0+3.0);
// pi = pi + 1.0/(i*4.0+1.0);
// pi = pi - 1.0/(i*4.0+3.0);
}
pi=pi*4.0;
printf("Pi=%lf\n",pi);
return 0;
}
我在CentOS 6机器上使用gcc版本4.4.4编译这两个代码。
[oz@centos ~]$ gfortran calcpi.f90 -o calcpi.fort.o
[oz@centos ~]$ gfortran calcpi.c -o calcpi.c.o
CPU是Intel(R)Xeon(R)CPU 5160 @ 3.00GHz。
所以,这是运行每个代码需要多长时间:
[oz@centos ~]$ time ./calcpi.c.o
Pi=3.141593
real 0m33.270s
user 0m33.261s
sys 0m0.000s
[oz@centos ~]$ time ./calcpi.fort.o
3.1415926553497115
real 0m27.220s
user 0m27.208s
sys 0m0.001s
Fortran的速度提高了约20%。 我的问题是什么是加速的最佳编译器标志,但仍然保持稳定性和准确性?
(是的,我知道man gcc,我想知道用户和意见)。
感谢您的意见。
结果,没有OpenMP pragma:
[oz@centos ~]$ time ./calcpi.c.o
Pi=3.141593
real 0m32.892s
user 0m32.885s
sys 0m0.001s
其他结果,无需更改代码本身:
$ gcc -O2 calcpi.c -o calcpi.c.o
$ time ./calcpi.c.o
Pi=3.141593
real 0m21.085s
user 0m21.078s
sys 0m0.000s
$ gfortran -O2 calcpi.c -o calcpi.c.o
$ time ./calcpi.fort.o
3.1415926553497115
real 0m26.892s
user 0m26.888s
sys 0m0.000s
答案 0 :(得分:14)
通过以双精度进行所有计算来修改Fortran程序,使其对应于C版本:
program calcpi
implicit none
integer :: i
integer, parameter :: p = selected_real_kind(15)
real(p) :: pi
pi=0.0_p
do i = 0,1000000000
pi = pi + 1.0_p/(4.0_p*i+1.0_p)
pi = pi - 1.0_p/(4.0_p*i+3.0_p)
end do
pi = pi * 4.0_p
write(*,*) pi
end program calcpi
在Xeon X3450(2.67 GHz)上使用GCC 4.4.3在x86_64-linux-gnu上使用-O2进行编译我得到以下时间:
$ time ./calcpi_c Pi=3.141593 real 0m13.903s user 0m13.860s sys 0m0.010s $ time ./calcpi_fort 3.1415926530880767 real 0m13.876s user 0m13.840s sys 0m0.000s
以下,它们或多或少难以区分。这就是人们对这样一个简单例子的期望。