几种编译器的性能比较

现在市面上,主流的C/C++编译器包括M$的CL、gcc、Intel的icl、PGI的pgcc及Codegear的bcc(原来属于Borland公司)。Windows上使用最多的自然是cl,而在更广阔的平台上,gcc则是C/C++编译器的首选。但要提到能力优化,排名就未必与它们的市场占有率一致了。

 

今天一时兴起,便做了一个各编译器数值性能的比较。测试的代码是一个求积分的程序,来源于intel编译器的例子程序,修改了一个头文件,以便每个编译器都能编译。

  1. #include <stdio.h>
  2. #include <stdlib.h> 
  3. #include <time.h> 
  4. #include <math.h>
  5. // Function to be integrated
  6. // Define and prototype it here
  7. // | sin(x) |
  8. #define INTEG_FUNC(x)  fabs(sin(x))
  9. // Prototype timing function
  10. double dclock(void);
  11. int main(void)
  12. {
  13.    // Loop counters and number of interior points
  14.    unsigned int i, j, N;
  15.    // Stepsize, independent variable x, and accumulated sum
  16.    double step, x_i, sum;
  17.    // Timing variables for evaluation   
  18.    double start, finish, duration, clock_t;
  19.    // Start integral from 
  20.    double interval_begin = 0.0;
  21.    // Complete integral at 
  22.    double interval_end = 2.0 * 3.141592653589793238;
  23.    // Start timing for the entire application
  24.    start = clock();
  25.    printf("     /n");
  26.    printf("    Number of    | Computed Integral | /n");
  27.    printf(" Interior Points |                   | /n");
  28.    for (j=2;j<27;j++)
  29.    {
  30.     printf("------------------------------------- /n");
  31.      // Compute the number of (internal rectangles + 1)
  32.      N =  1 << j;
  33.      // Compute stepsize for N-1 internal rectangles 
  34.      step = (interval_end - interval_begin) / N;
  35.      // Approx. 1/2 area in first rectangle: f(x0) * [step/2] 
  36.      sum = INTEG_FUNC(interval_begin) * step / 2.0;
  37.      // Apply midpoint rule:
  38.      // Given length = f(x), compute the area of the
  39.      // rectangle of width step
  40.      // Sum areas of internal rectangle: f(xi + step) * step 
  41.      for (i=1;i<N;i++)
  42.      {
  43.         x_i = i * step;
  44.         sum += INTEG_FUNC(x_i) * step;
  45.      }
  46.      // Approx. 1/2 area in last rectangle: f(xN) * [step/2] 
  47.      sum += INTEG_FUNC(interval_end) * step / 2.0;
  48.      printf(" %10d      |  %14e   | /n", N, sum);
  49.    }
  50.    finish = clock();
  51.    duration = (finish - start);
  52.    printf("     /n");
  53.    printf("   Application Clocks   = %10e  /n", duration);
  54.    printf("     /n");
  55.    return 0;
  56. }

当然,这个代码来自于intel,当然非常适合intel的编译器。以下的测试在Intel Core 2 Duo上进行。

 

gcc (GCC TDM-2 for MinGW) 4.3.0  VC 9.0 (cl 15.00.21022.08)  Intel (icl 10.1)  PGI (pgcc 7.16)  CodeGear (bcc32 6.10) 
禁止优化
-O0 /Od -Od -O0 -Od
17161 14461 12441 10514 13400
17133 14430 11687 9956 12917
17155 14476 11871 10099 13026
编译选项 -O2
13011 7737 4540 9348 12636
16571 7706 4185 9148 13026
16573 7706 4042 9183 13057
针对平台的优化
-march=core2 -O2 /arch:SSE2 /O2 -QxT -tp core2 -O2
16060 7710 1938 9578

 

测试的结果说明,在数值计算方法,intel的编译器是非常利害的,特别是针对某CPU的优化,能提高很多性能。GCC表现却有些让人失望。在禁止优化到-O2级优化的对比中,可以看出intel与m$的编译器的优化效果是非常明显的,而其它编译器优化后的提高非常有限。如果给个排名,那么将是 icl>cl>pgcc>bcc>gcc。

 

另外,在一台P4 1.5G的机器,linux环境下,测试得到

gcc icc pgCC
-O2 -O2 -O2
24920000 10840000 22270000
-O0 -O0 -O0
28290000 19210000 24320000
-march=pentium4 -O2 -xN -tp piv -O2
24990000 6640000 22150000

 

同样,还是intel的表现最好,而gcc最差。

 

又在Athlon X2 4800+, Linux上测试,得到下表

gcc icc pgcc
-O0 -O0 -O0
9390000 14950000 9950000
-O2 -O2 -O2
8910000 9240000 9400000
-march=amdfam10 -O2 -msse3 -O2 -tp k8-32 -O2
8800000 3800000 9030000

 

虽然icc主要是针对intel的处理器,但只要优化选项找对,同样能带给amd cpu性能的巨大提高。gcc也回归到普通水平。奇怪的是pgi的编译器,估计是我还没找到好的选项吧。

 

总结看来,在数值计算方法,“最快”的选择应该属于intel

你可能感兴趣的:(优化,linux,gcc,测试,编译器,Borland)