【问题标题】:exp function run time comparison ifort vs gfortranexp 函数运行时间比较 ifort 与 gfortran
【发布时间】:2021-05-18 08:33:43
【问题描述】:

我写了这段代码:

program exponent
    implicit none

    real(8) :: sum
    integer(8) :: i
    integer :: limit
    real :: start, end

    sum = 0d0
    limit = 10000000
    call CPU_TIME(start)
    do i=1, limit
        sum = sum + exp(i*1.d0/limit)
    end do
    call CPU_TIME(end)
    print *, sum
    print '("Time = ",f6.3," seconds.")',end-start
end program exponent

我在 CentOS Linux 7 上使用 gfortran 10.1.0 和 ifort 19.1.3.304 编译它:

ifort *.f90 -O3 -o intel.out

gfortran *.f90 -O3 -o gnu.out

输出如下:

gnu:

17182819.143730670
Time = 0.248 seconds.

英特尔:

17182819.1437313
Time = 0.051 seconds.

我跑了几次,每次的运行时间都差不多。

为什么 ifort 比 gfortran 快,我怎样才能让 gfortran 像 ifort 一样快?

【问题讨论】:

  • 这看起来像是 exp 实现的不同之处。当 GCC 使用 GLIBC 时,英特尔可能已经在 O3 上偷工减料了。但是,请尝试以相反的顺序运行测试。测试太小,无法真正让 CPU 完全启动。另外,只为循环计时。
  • 我可以确认差异。在没有 CPU 节流的计算机上,尝试一次就足够了。循环中的多次尝试没有任何区别。 -ffast-math 使 gfortran 稍微快一点,但速度并不快。
  • 就像@VladimirF 已经说过只有时间循环,当使用time 时,您还记录操作系统需要启动/关闭应用程序、加载库等的时间。time不可 用于基准测试。
  • 应该添加我的时间只是从计时循环开始。再三考虑,英特尔可能正在对循环进行矢量化或以其他方式重新排序,而不是近似 exp
  • 在问题中添加了编译器版本和操作系统

标签: performance assembly fortran gfortran intel-fortran


【解决方案1】:

ifort 速度更快,主要是因为它使用自己的优化数学库,称为 SVML(由英特尔编译器提供)。这个库通常更快,因为它提供了优化的 vectorized 原语,即使没有-ffastmath。此外,英特尔编译器倾向于更好地向量化循环(尤其是像这样的缩减)。

您可以看到on GodBolt 的区别:ifort 版本通过一次处理 2 个数字来向量化循环,而 gfortran 版本使用较慢的标量指数。

请注意,由于 AVX 指令集,使用 -mavx2 有助于 ifort 生成更快的代码。使用 AVX-512 指令(如果在目标机器上可用)可能会更快。 gfortran 可以在 GodBolt 上使用 -march=native 对循环进行矢量化(但奇怪的是,不能使用 -march=skylake-ffast-math)。

【讨论】:

  • 感谢您的回答!我在 ifort 编译中添加了 -no-vec,在 gfortran 中添加了 -fno-tree-vectorize。新的时间是:ifort - 0.142 秒,gnu - 0.248 秒。因此,确实,矢量化参与了运行时间差异,但 ifort 仍然更快。有没有办法让 gfortran 和 ifort 一样快?
  • 可能是的,通过在 gfortran 版本中链接 SVML。我不确定它是否得到很好的支持。至少,在最坏的情况下应该可以手动使用 SVML。或者,您可以使用安装在 ifort 版本中的标准 libmath,尽管在这种情况下两个版本都会很慢。另一种解决方案是编写自己的矢量化代码,但这很麻烦(尽管它们是很好的研究论文)。
  • @steve 现在的实现速度明显加快。 GNU 实现已经使用了一些优化的基于表的算法,但最先进的算法(如在 SVML 中使用的算法)优于它(尤其是由于矢量化,但不仅如此)。这是一篇相当新的论文的参考:“SIMD 架构上的快速指数计算”(2015 年)。
  • 即使没有 -ffast-math - 请注意 ICC(我假设 ifort 的)默认值是 -fp-model fast=1。不像fp-model fast=2 那样激进,但在重要的方面仍然更像-ffast-math。例如它允许 ifort 假装 FP 数学是关联的并向量化数组的总和,或者在这种情况下 addpd 在一对向量化的 exp 结果上而不是单独将每个元素添加到标量和 inside 循环.
  • 奇怪的是 gfortran 只会使用矢量化 exp-march=skylake-avx512(这些云服务器上的原生),而不是 -march=skylake。即使-mveclibabi=svmlacml 也无济于事。 sourceware.org/glibc/wiki/libmvec 说 gcc4.9 应该能够向量化 C 函数,如 cos()-O1 -fopenmp -ffast-math -lm -mavx2-O1 -ftree-loop-vectorize -ffast-math -lm -mavx。 (-O3 包括 -ftree-vectorize)
猜你喜欢
  • 2014-04-14
  • 1970-01-01
  • 1970-01-01
  • 2018-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多