2011-01-13 5 views
5

일부 코드를 최적화하는 방법을 찾으려고합니다. 여기있다 :인라인 된 함수는 여전히 .prof 파일에 표시됩니다.


{-# 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 시스템에서 리눅스)로 컴파일 할 때

GHC --make -O2 Vec.hs -prof -auto - 모든 -fforce-recomp

실행

VEC + RTS -p

Vec.prof 파일을 보면

,


내가 함수 VX와 VY의 시간의 상당 부분을 볼
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 

.

왜 그럴까요? SPECIALIZE INLINE 플러그인이 함수를 사라지게 만들 것이라고 생각했습니다. 비 다형성

data Vec3D = Vec3D {vx, vy, vz :: !Double} deriving Show 

기능의 VX, VY를 사용하는 경우

은 VZ는 비용 센터로 표시되지 않습니다.

+1

실제로 코어를 보았습니까? '-ddump-core'로 컴파일하고 무슨 일이 일어나는지보십시오. – fuz

답변

2

이것은 인라인을 포함하여 GHC가 일반적으로 수행하는 많은 최적화를 금지하는 -auto-all을 사용하는 부작용이라고 생각됩니다. 비 다형성 버전의 차이는 실제로 다형성 때문이 아니라 vx, vyvz이 레코드 구문을 통해 정의 되었기 때문인 것으로 의심됩니다.

-auto-all을 사용하는 대신 모듈에 내보내기 목록을 추가하고 "-auto"로 컴파일하거나 SCC pragma를 통해 수동으로 코스트 센터를 설정하십시오. 어쨌든 종종 let-bound 함수에 그들을 설정하기를 원하기 때문에 SCC pragma를 사용합니다. -auto-all은 그렇게하지 않을 것입니다.

2

답장에 댓글을 쓰는 방법을 알 수 없으므로이 답변에 댓글을 남깁니다.

먼저 답해 주셔서 감사합니다.

FUZxxl : -ddump-core를 시도했는데 -ddump-core가 인식 할 수없는 플래그라는 오류 메시지가 나타납니다. 아마도 당신은 Real World Haskell이 추천했던 책인 --ddump-simple을 사용 했겠지만 출력 결과를 읽는 방법을 모르겠다. 출력 파일에서 "vx"등을 보았지만 결코 보지 못했습니다. 나는 핵심을 읽는 법을 배워야한다고 생각한다. 거기에 좋은 가이드가 있습니까?

존 : 내가 제대로 읽고 있어요 경우 GHC의 flag reference documentation에 따르면, -auto 및 -auto 모두 모두, 기능 하지 표시된 INLINE에 _scc_s 추가되어 있습니다. -auto가 나를 위해 작동하는지 확인하기 위해 Vec3 코드가 별도의 파일/모듈에 있고 Vec3 (Vec3), vx, vy, vz 및 점이 내 보낸 다른 테스트 사례를 만들었습니다. 이 모듈을 Main.hs 파일로 가져 왔습니다. 이것들을 -auto로 컴파일하면 .prof 파일에서 여전히 vx, vy, vz를 보았습니다.

는 다시 : 차이가 대신 다형성의 기록 구문에 기인 될 수 있다는 의견, 나는 여전히

data Vec3 a = Vec3 {vx, vy, vz :: !a} 

VX, VY 및 VZ를 정의 할 때 때문에 차이 때문에 다형성에 가능성이 있다고 생각 .prof 파일에 나타났습니다.

타이드

+0

질문에 실제 계정을 사용해야합니다. 그런 계좌를 가지고 있다면 명성이 충분히 높을 때 먼저 자신의 질문에 대한 답을 남길 수 있습니다. – fuz

+0

조언 해 주셔서 감사합니다. 나는 지금 그것을했다. – Tad

관련 문제