gpt4 book ai didi

optimization - 在 fortran 中访问虚拟变量会阻止优化吗?

转载 作者:行者123 更新时间:2023-12-03 16:12:49 26 4
gpt4 key购买 nike

我正在尝试优化一些 Fortran 代码并注意到一些我试图理解的令人惊讶的行为。 progb 的运行速度比 proga 快 3 到 4 倍。唯一的区别是 progb 中的赋值 "d = 2"而不是 proga 中的 "d = b",所以天真地这些应该是等效的:

  program proga
implicit none

call hist(2)
stop
end

subroutine hist(b)
implicit none
integer, intent(in):: b
integer d,i,p(200000000)

d = b
do i=1,200000000
p(i) = i/d
end do
write(*,*) p(1)
end


program progb
implicit none

call hist(2)
stop
end

subroutine hist(b)
implicit none
integer, intent(in):: b
integer d,i,p(200000000)

d = 2
do i=1,200000000
p(i) = i/d
end do
write(*,*) p(1)
end

我用“gfortran proga.f -O3”和progb 编译。这发生在 Debian 上的 gcc 4.9.2 版以及 cygwin 上的 gcc 5.4.0 版上。

当我在没有 -O3 标志的情况下编译时,它们都以相同的速度运行,所以听起来编译器也无法优化 proga。什么优化不能在 proga 上完成,为什么?

我已经为这篇文章精简了我的代码(我的实际代码做了一些有用的事情!)。常量 200000000 应该足够大以提供重要的运行时间。写入可防止循环被优化掉。

最佳答案

值 2 是一个非常特殊的值。如果编译器知道它总是被 2 除,它可以只移动位而不是进行算术计算。然而,在 progb编译器必须使用任何可能的整数值进行计数,因此必须实现实数除法,而不仅仅是位移。

因此,访问参数不会抑制任何优化。使用固定值允许进行一些特定的优化。特别是如果它是 2 的幂。

https://godbolt.org/z/TcJxYK 查看差异

通用版本使用

idiv    ecx

除以 2 的版本使用
shr     edx, 31
add eax, edx
sar eax
idiv指令比移位和加法慢得多。

对于非 2 的幂,它仍然是可优化的,但它通常还涉及算术运算,如乘法、加法和减法,而不仅仅是位移。然而,这些比除法更快。除法是一个非常缓慢的操作。

正如史蒂夫指出的那样,使用 -fwhole-program使编译器能够将所有单元编译在一起,并且它可以假设它不需要生成不需要的子例程。

顺便说一句,对于我在 godbolt 链接中使用的简化子程序,gfortran 优化了对子程序的调用,即使没有 -fwhole-program .

关于optimization - 在 fortran 中访问虚拟变量会阻止优化吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58772811/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com