我正在试图弄清楚如何优化一些代码。这是:
{-# 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不显示为成本中心。
答案 0 :(得分:2)
我怀疑这是使用-auto-all
的副作用,这会抑制GHC通常会执行的许多优化,包括内联。我怀疑你的非多态版本的差异实际上是由于vx
,vy
和vz
是通过记录语法定义而不是因为多态(但我可能错了) )。
不是使用-auto-all,而是尝试向模块添加导出列表并使用“-auto”进行编译,或者通过SCC编译指示手动设置成本中心。我通常使用SCC编译指示,因为我经常想要将它们设置在let-bound函数上,而-auto-all将不会这样做。
答案 1 :(得分:2)
我无法弄清楚如何对回复发表评论,所以我在这个答案中发表评论。
首先,感谢您的回答。
FUZxxl:我尝试了-ddump-core,并收到一条错误消息,即-ddump-core是一个无法识别的标志。也许你的意思是-ddump-simpl,这是Real World Haskell推荐使用的书,但我担心我不知道如何阅读输出。我查看输出文件中的“vx”等,但从未见过它们。我想我应该学习如何阅读核心。那有什么好的指南吗?
John:根据GHC的flag reference documentation,如果我正确读取它,那么-auto和-auto-all都应该将_scc_s添加到标记为INLINE的函数而不是。为了看看-auto是否适合我,我创建了另一个测试用例,其中Vec3代码位于一个单独的文件/模块中,Vec3(Vec3),vx,vy,vz和dot导出。我将此模块导入Main.hs文件。用-auto编译这些,我仍然在.prof文件中看到了vx,vy,vz。
Re:您的评论认为差异可能是由于记录语法而不是多态性,我认为差异更可能是由于多态性,因为当我定义时
data Vec3 a = Vec3 {vx, vy, vz :: !a}
vx,vy和vz仍显示在.prof文件中。
泰德