클래스 제약 조건이있는 함수를 GHC에서 특수화하는 데 문제가 있습니다. 여기 내 문제의 최소한의 예를 가지고 : Foo.hs 및 Main.hs을 . 두 파일은 컴파일 (GHC 7.6.2, ghc -O3 Main
)되어 실행됩니다.
참고 :
Foo.hs
실제로 제거되었습니다. 제약 조건이 필요한 이유를 보려면 여기에서 더 많은 코드를 볼 수 있습니다 . 코드를 단일 파일에 넣거나 기타 여러 가지 사소한 변경을 수행하면 GHC는 단순히 호출을 인라인합니다 plusFastCyc
. 실제 코드에서는 표시되지 않은 경우 plusFastCyc
에도 GHC가 인라인 하기 에 너무 커서이 문제 가 발생하지 않습니다 INLINE
. 요점은 인라인이 아닌에 대한 호출 을 특수화 하는 plusFastCyc
것입니다. plusFastCyc
실제 코드의 많은 곳에서 호출되므로 GHC가 강제로 수행 할 수 있다고해도 그러한 큰 기능을 복제하는 것은 바람직하지 않습니다.
관심의 코드입니다 plusFastCyc
에 Foo.hs
여기, 복제 :
{-# INLINEABLE plusFastCyc #-}
{-# SPECIALIZE plusFastCyc ::
forall m . (Factored m Int) =>
(FastCyc (VT U.Vector m) Int) ->
(FastCyc (VT U.Vector m) Int) ->
(FastCyc (VT U.Vector m) Int) #-}
-- Although the next specialization makes `fcTest` fast,
-- it isn't useful to me in my real program because the phantom type M is reified
-- {-# SPECIALIZE plusFastCyc ::
-- FastCyc (VT U.Vector M) Int ->
-- FastCyc (VT U.Vector M) Int ->
-- FastCyc (VT U.Vector M) Int #-}
plusFastCyc :: (Num (t r)) => (FastCyc t r) -> (FastCyc t r) -> (FastCyc t r)
plusFastCyc (PowBasis v1) (PowBasis v2) = PowBasis $ v1 + v2
Main.hs
: 파일은 두 드라이버가 vtTest
, 2 ~ 3 초 실행하고 fcTest
사용 -O3으로 컴파일시 ~ 83초에서 실행되는, forall
'D 전문화.
핵심 쇼 에 대한 vtTest
테스트, 추가 코드가 전문화되고있는 Unboxed
이상 벡터 Int
일반적인 벡터 코드가 사용되는 동안, 등의, fcTest
. 라인 (10)에, 당신은 GHC이의 전문 버전 쓰기 않는 것을 볼 수 있습니다 plusFastCyc
나는이 규칙이 라인 (270) (에 발사한다고 생각 라인 전문화에 대한 규칙은 라인 225에 167의 일반 버전에 비해 main6
통화 iterate main8 y
그래서 main8
입니다 plusFastCyc
전문화해야 할 곳 )
내 목표는 전문화 하여 fcTest
최대한 빨리 만드는 것 vtTest
입니다 plusFastCyc
. 이 작업을 수행하는 두 가지 방법을 찾았습니다.
- 명시 적으로 호출
inline
에서GHC.Exts
에서fcTest
. - 의
Factored m Int
제약 조건을 제거하십시오plusFastCyc
.
실제 코드 기반 plusFastCyc
에서 자주 사용되는 작업이고 매우 큰 기능 이기 때문에 옵션 1은 만족스럽지 않으므로 사용 시마다 인라인되지 않아야합니다. 대신 GHC는의 특수 버전을 호출해야합니다 plusFastCyc
. 실제 코드에는 제약 조건이 필요하기 때문에 옵션 2는 실제로 옵션이 아닙니다.
내가 사용하는 (그리고 사용하지 않는) 다양한 옵션을 시도했습니다 INLINE
, INLINABLE
그리고 SPECIALIZE
, 그러나 아무것도 작동하는 것 같다 없습니다. ( 편집 : plusFastCyc
예제를 작게 만들기 위해 너무 많이 제거 했을 INLINE
수 있으므로 함수가 인라인 될 수 있습니다.이 코드 plusFastCyc
는 너무 커서 실제 코드에서는 발생하지 않습니다 .)이 특정 예제에서는 그렇지 않습니다. 어떤 점점 match_co: needs more cases
나 RULE: LHS too complicated to desugar
(그리고 여기에서 나는 많은 얻고 있었다 불구하고) 경고를 match_co
예를 최소화하기 전에 경고를. 아마도 "문제"는 Factored m Int
규칙 의 제약 일 것입니다. 해당 제약 조건을 변경하면 fcTest
최대한 빨리 실행됩니다 vtTest
.
GHC가 싫어하는 일을하고 있습니까? GHC가 왜 전문가가 아닌데 plusFastCyc
어떻게 만들 수 있습니까?
최신 정보
GHC 7.8.2에서도 문제가 지속되므로이 질문은 여전히 관련이 있습니다.
m
, 즉 전문을 시도했습니다M
. 이것으로 작업이 완료되었지만 실제 프로그램에서 특정 팬텀 유형을 구체화 할 수는 없습니다.