首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >GHC中自动专业化的传递性?

GHC中自动专业化的传递性?

提问于 2017-12-22 10:31:49
回答 2关注 0查看 344

从GHC 7.6 文档:

[Y]你通常甚至不需要SPECIALIZE附注。当编译一个模块M时,GHC的优化器(带有-O)会自动考虑在M中声明的每个顶层重载函数,并且专门针对它在M中调用的不同类型。优化器还会考虑每个导入的INLINABLE重载函数,并专门针对它在M中被称为的不同类型

此外,给定一个函数f的SPECIALIZE pragma,GHC将自动为f调用的任何类重载函数创建专门化,如果它们与SPECIALIZE pragma在同一个模块中,或者它们是INLINABLE; 等等。

因此,GHC应该自动专门化一些标记为INLINABLE 无标注的大部分/全部(?)功能,如果使用明确的附注,则专门化是传递性的。我的问题是:汽车专业化传递?

具体来说,这是一个小例子:

Main.hs:
import Data.Vector.Unboxed as U
import Foo
main =
    let y = Bar $ Qux $ U.replicate 11221184 0 :: Foo (Qux Int)
        (Bar (Qux ans)) = iterate (plus y) y !! 100
    in putStr $ show $ foldl1' (*) ans

Foo.hs:
module Foo (Qux(..), Foo(..), plus) where
import Data.Vector.Unboxed as U
newtype Qux r = Qux (Vector r)
-- GHC inlines `plus` if I remove the bangs or the Baz constructo
data Foo t = Bar !t
           | Baz !t
instance (Num r, Unbox r) => Num (Qux r) where
    {-# INLINABLE (+) #-}
    (Qux x) + (Qux y) = Qux $ U.zipWith (+) x y
{-# INLINABLE plus #-}
plus :: (Num t) => (Foo t) -> (Foo t) -> (Foo t)
plus (Bar v1) (Bar v2) = Bar $ v1 + v2

GHC专门调用plus,但并没有专门(+)的Qux Num杀死性能实例。

但是,一个明确的杂注

{-# SPECIALIZE plus :: Foo (Qux Int) -> Foo (Qux Int) -> Foo (Qux Int) #-}

导致文档指出传递专业化,所以(+)是专门的,代码是30倍以上(都编译-O2)。这是预期的行为?我是否应该只希望(+)用一个明确的附注来传递?

回答

和开发者交流更多问题细节吧,去 写回答
相关文章

相似问题

相关问答用户
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档