为什么gcc数学库效率如此低下? [英] Why is the gcc math library so inefficient?

查看:98
本文介绍了为什么gcc数学库效率如此低下?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我将一些fortran代码移植到c时,令我惊讶的是,使用ifort(intel fortran编译器)编译的fortran程序和使用gcc编译的c程序之间的大部分执行时间差异来自三角函数的求值.功能(sincos).这让我感到惊讶,因为我曾经相信答案解释的内容是,正弦和余弦之类的功能是在微处理器内部的微代码中实现的.

When I was porting some fortran code to c, it surprised me that the most of the execution time discrepancy between the fortran program compiled with ifort (intel fortran compiler) and the c program compiled with gcc, comes from the evaluations of trigonometric functions (sin, cos). It surprised me because I used to believe what this answer explains, that functions like sine and cosine are implemented in microcode inside microprocessors.

为了更明确地发现问题,我在fortran中制作了一个小型测试程序

In order to spot the problem more explicitly I made a small test program in 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 Q6600处理器和3.6.9-1-ARCH x86_64 Linux上 我得到ifort version 12.1.0

On intel Q6600 processor and 3.6.9-1-ARCH x86_64 Linux I get with 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实现中的实现方式类似吗?如果这是真的,瓶颈在哪里?

This is almost a factor of 10 difference! Can I still believe that the gcc implementation of cos is a wrapper around the microprocessor implementation in a similar way as this is probably done in the intel implementation? If this is true, where is the bottle neck?

编辑

根据评论,启用的优化应该可以提高性能.我的意见是,优化不会影响库函数……这并不意味着我不会在非平凡的程序中使用它们.但是,这是另外两个基准(现在在我的家用计算机intel core2上)

According to comments, enabled optimizations should improve the performance. My opinion was that optimizations do not affect the library functions ... which does not mean that I don't use them in nontrivial programs. However, here are two additional benchmarks (now on my home computer 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

您(评论员)想到了哪些特定的优化?在这个特定示例中,编译器如何利用多核处理器,其中每个迭代都取决于前一个的结果?

Which particular optimizations did you (commentators) have in mind? And how can compiler exploit a multi-core processor in this particular example, where each iteration depends on the result of the previous one?

编辑2

Daniel Fisher和Ilmari Karonen的基准测试使我认为问题可能与gcc的特定版本(4.7.2)有关,也许与我正在使用的gcc的特定版本(Arch x86_64 Linux)有关.我的电脑.所以我在intel core i7框上用debian x86_64 Linuxgcc version 4.4.5ifort version 12.1.0

The benchmark tests of Daniel Fisher and Ilmari Karonen made me think that the problem might be related to the particular version of gcc (4.7.2) and maybe to a particular build of it (Arch x86_64 Linux) that I am using on my computers. So I repeated the test on the intel core i7 box with debian x86_64 Linux, gcc version 4.4.5 and 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

对我来说,这是一个非常可以接受的性能差异,这绝对不会让我问这个问题.看来我必须在Arch Linux论坛上问这个问题.

For me this is a very much acceptable performance difference, which would never make me ask this question. It seems that I will have to ask on Arch Linux forums about this issue.

但是,仍然很欢迎您对整个故事进行解释.

However, the explanation of the whole story is still very welcome.

推荐答案

大部分是由于数学库中的差异.需要考虑的几点:

Most of this is due to differences in the math library. Some points to consider:

  • 是的,带有x87单元的x86处理器具有fsin和fcos指令.但是,它们是用微码实现的,没有特殊的原因为什么它们必须比纯软件实现更快.
  • GCC没有自己的数学库,而是使用提供的系统.在Linux上,通常由glibc提供.
  • 32位x86 glibc使用fsin/fcos.
  • x86_64 glibc使用使用SSE2单元的软件实现.长期以来,这比仅使用x87指令的32位glibc版本要慢很多.但是,已经进行了一些改进(最近有所改进),因此根据您所使用的glibc版本,情况可能不再像以前那样糟糕.
  • 英特尔编译器套件拥有非常快速的数学库(libimf).此外,它还包括矢量化的先验数学函数,这些函数通常可以进一步加快使用这些函数的循环.
  • Yes, the x86 processors with the x87 unit has fsin and fcos instructions. However, they are implemented in microcode, and there is not particular reason why they must be faster than a pure software implementation.
  • GCC does not have it's own math library, but rather uses the system provided one. On Linux this is typically provided by glibc.
  • 32-bit x86 glibc uses fsin/fcos.
  • x86_64 glibc uses software implementations using the SSE2 unit. For a long time, this was a lot slower than the 32-bit glibc version which just used the x87 instructions. However, improvements have (somewhat recently) been made, so depending on which glibc version you have the situation might not be as bad anymore as it used to be.
  • The Intel compiler suite is blessed with a VERY fast math library (libimf). Additionally, it includes vectorized transcendental math functions, which can often further speed up loops with these functions.

这篇关于为什么gcc数学库效率如此低下?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆