haskell - 内联函数仍然显示在 .prof 文件中

标签 haskell profiler ghc

我正在尝试找出如何优化一些代码。这是:

<小时/>
{-# 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 通常执行的许多优化,包括内联。我怀疑非多态版本的差异实际上是由于 vxvyvz 是通过记录语法定义的,而不是因为多态性(但我可能是错的)。

不要使用 -auto-all,而是尝试将导出列表添加到模块并使用“-auto”进行编译,或者通过 SCC 编译指示手动设置成本中心。无论如何,我通常使用 SCC 编译指示,因为我经常想将它们设置在 let 绑定(bind)函数上,而 -auto-all 则不会这样做。

关于haskell - 内联函数仍然显示在 .prof 文件中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4676645/

相关文章:

haskell - 无法使用 Esqueleto 编写双左连接

apache-flex - 更好的Flex内存分析工具

java - 运行在 Redhat 上的配置文件 Tomcat 实例

haskell - "module [...] is defined in multiple files"Haskell 编译错误

haskell - 抑制运行时错误 "Irrefutable pattern failed for pattern Data.Maybe.Just b"

Haskell仿函数错误

function - 将 2 个参数传递给 Haskell 中的函数

java - 是否有 IntelliJ Java Profiler

haskell - rank-2 类型的模式匹配

haskell - GHC 和 Haskell 平台有什么区别?