专门针对相关的多态函数而不进行内联

时间:2017-03-04 22:15:23

标签: performance haskell inline ghc

这是一个重复我正在处理的真正问题的最小例子:

一个库模块:

module S where

import Lib

newtype Foo = Foo Int
    deriving Show

instance S Foo where
  mix (Foo x) y = Foo (x+y)

另一个,可能由用户定义:

Main

我们的module Main where import Lib import S import Criterion.Main main = defaultMain [ bench "foo" $ whnf (hash (Foo 1)) (2::Int,3::Int) ]

ghc --make -Wall -O2 -rtsopts -ddump-to-file -ddump-simpl -dsuppress-module-prefixes -dsuppress-uniques -ddump-core-stats -ddump-inlinings -fforce-recomp Main.hs

使用INLINE编译ghc 8.0.1。

上述基准测试以4μs运行。但是,如果我们在hash中的两个Lib声明中添加Main个pragma,我们会看到我们想要的预期特化,并获得 66 ns 的运行时。

但我真的不想内联所有内容(在用户的真实hash中,她可能在同一类型上多次调用H),我只想要针对每种组合专门使用该功能用户代码中的SINLINE实例

INLINABLE pragma更改为{-# SPECIALIZE hash :: H a=> Foo -> a -> Foo #-} 导致旧行为回归(我认为,因为GHC的内联启发式方法仍在发挥作用)。然后我尝试添加

Main

同时发送SIgnoring useless SPECIALISE pragma for class method selector ‘hash’ 模块,但这会生成

S

...警告和相同的错误代码。

一些限制:

  • 要求每个H实例声明包含有限数量的pragma(可能与H相关)
  • ,这是不可取的。
  • 同样适用于SPECIALIZE
  • 要求用户为SH的每个组合执行<html> <head lang="en"> <meta charset="UTF-8"> </head> <body> <!-- language: PHP --> <?php if(isset($_POST['age'])) { echo $_POST['age']; } ?> <h1>Fill in the form</h1> <form method="POST" action="http://localhost/try/"> <p>age:</p> <input type="text" name="age"> <input type="submit" name="submit"> </form> 是不可接受的。

没有INLINE可以做到这一点吗?

这可能与Specialization with Constraints和相关的trac ticket https://ghc.haskell.org/trac/ghc/ticket/8668相同,但我想我会再次提出并可能将此作为GHC Trac的一个简单示例发布。

编辑:继续开通ghc门票:https://ghc.haskell.org/trac/ghc/ticket/13376

0 个答案:

没有答案