에서 워드 프로세서 GHC 7.6에 대한 :
[Y] 당신은 종종 처음에는 SPECIALIZE pragma가 필요하지 않습니다. 모듈 M을 컴파일 할 때 GHC의 옵티 마이저 (-O 포함)는 M에 선언 된 각각의 최상위 오버로드 된 함수를 자동으로 고려하여 M에서 호출되는 다양한 유형에 특화합니다. 옵티마이 저는 가져온 각 INLINABLE 오버로드 된 함수, M에서 호출되는 다양한 유형에 특화되어 있습니다.
과
또한 함수 f에 대한 SPECIALIZE pragma가 주어지면 GHC는 f에 의해 호출되는 모든 type-class-loaded 함수에 대해 SPECIALIZE pragma와 동일한 모듈에 있거나 INLINABLE 인 경우 자동으로 전문화를 작성합니다. 전 이적으로.
따라서 GHC는 pragma 없이 표시된 일부 / most / all (?) 함수를 자동으로 특수화해야 하며 명시 적 pragma를 사용하면 전문화가 전이됩니다. 내 질문은 : 자동 전문화 전이인가?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 constructor
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
그러나 명시 적 pragma
{-# SPECIALIZE plus :: Foo (Qux Int) -> Foo (Qux Int) -> Foo (Qux Int) #-}
결과 전이 워드 프로세서는 표시로 전문화, 그래서 (+)
전문 및 코드는 빠른 (모두 컴파일 30 배이다 -O2
). 이것이 예상되는 동작입니까? (+)
명시 적 pragma를 전 이적으로 전문화 해야합니까 ?
최신 정보
7.8.2에 대한 문서는 변경되지 않았으며 동작은 동일하므로이 질문은 여전히 관련이 있습니다.
plus
한 하지 INLINABLE 2로 표시) simonpj이 일부 티켓 코드에가는 인라인했지만, 지적의 핵심 내 예는 어떤 함수도 인라인되지 않았 음을 보여줍니다 (특히, 두 번째 Foo
생성자를 제거 할 수 없었습니다 . 그렇지 않으면 GHC 인라인 된 항목).
plus (Bar v1) = \(Bar v2)-> Bar $ v1 + v2
콜 사이트에서 LHS가 완전히 적용되도록을 정의하면 어떻게됩니까 ? 인라인 된 다음 전문화가 시작됩니까?
plus
이러한 링크로 인해 특별히 적용 하라는 요청이 있었지만 실제로는 전문성 이 떨어 졌습니다 plus
. 나는 그것에 대한 설명이 없지만 다른 질문으로 남겨 두거나이 질문에 대한 답변으로 해결되기를 바랍니다.