我正在尝试找出如何优化一些代码。这是:
<小时/>{-# OPTIONS_GHC -funbox-strict-fields #-}
data Vec3 a = Vec3 !a !a !a
vx :: Vec3 a -> a
vx (Vec3 x _ _) = x
{-# SPECIALIZE INLINE vx :: Vec3 Double -> Double #-}
vy :: Vec3 a -> a
vy (Vec3 _ y _) = y
{-# SPECIALIZE INLINE vy :: Vec3 Double -> Double #-}
vz :: Vec3 a -> a
vz (Vec3 _ _ z) = z
{-# SPECIALIZE INLINE vz :: Vec3 Double -> Double #-}
dot :: (Num a) => Vec3 a -> Vec3 a -> a
dot u v = (vx u * vx v) + (vy u * vy v) + (vz u * vz v)
{-# SPECIALIZE INLINE dot :: Vec3 Double -> Vec3 Double -> Double #-}
type Vec3D = Vec3 Double
-- just make a bunch of vecs to measure performance
n = 1000000 :: Double
v1s = [Vec3 x y z | (x, y, z) <- zip3 [1 .. n] [2 .. n + 1] [3 .. n + 2]]
:: [Vec3D]
v2s = [Vec3 x y z | (x, y, z) <- zip3 [3 .. n + 2] [2 .. n + 1] [1 .. n]]
:: [Vec3D]
dots = zipWith dot v1s v2s :: [Double]
theMax = maximum dots :: Double
main :: IO ()
main = putStrLn $ "theMax: " ++ show theMax
<小时/>
当我使用 ghc 6.12.1 进行编译时(i486 机器上的 ubuntu linux)
ghc --make -O2 Vec.hs -prof -auto-all -fforce-recomp
然后运行
Vec +RTS -p
查看 Vec.prof 文件,
<小时/>COST CENTRE MODULE %time %alloc
v2s Main 30.9 36.5
v1s Main 27.9 31.3
dots Main 27.2 27.0
CAF GHC.Float 4.4 5.2
vy Main 3.7 0.0
vx Main 2.9 0.0
theMax Main 2.2 0.0
<小时/>
我发现函数 vx 和 vy 占用了很大一部分时间。
这是为什么呢?我认为 SPECIALIZE INLINE pragma 会使 这些功能消失了。
当使用非多态时
data Vec3D = Vec3D {vx, vy, vz :: !Double} deriving Show
函数 vx、vy、vz 不显示为成本中心。
最佳答案
我怀疑这是使用 -auto-all
的副作用,它会抑制 GHC 通常执行的许多优化,包括内联。我怀疑非多态版本的差异实际上是由于 vx
、vy
和 vz
是通过记录语法定义的,而不是因为多态性(但我可能是错的)。
不要使用 -auto-all,而是尝试将导出列表添加到模块并使用“-auto”进行编译,或者通过 SCC 编译指示手动设置成本中心。无论如何,我通常使用 SCC 编译指示,因为我经常想将它们设置在 let 绑定(bind)函数上,而 -auto-all 则不会这样做。
关于haskell - 内联函数仍然显示在 .prof 文件中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4676645/