2011-01-13 9 views
5

Próbuję dowiedzieć się, jak zoptymalizować kod. Oto ona:Funkcje podkreślone nadal pojawiają się w pliku .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 

Kiedy skompilować z GHC 6.12.1 (Ubuntu Linux na maszynie i486)

ghc --make -O2 Vec.hs -prof -Auto -wszystkie -fforce-ReComp

i uruchomić

vec + RTS -p

Patrząc na pliku Vec.prof,


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 

widzę, że vx i vy funkcja zająć znaczną część czasu.

Dlaczego tak jest? Pomyślałem, że pragma SPECIALIZE INLINE spowoduje, że te funkcje znikną.

Podczas używania non-polimorficzny

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

funkcje VX, VY, VZ nie wykazują jako centrum kosztów.

+1

Czy rzeczywiście spojrzałeś na rdzeń? Spróbuj skompilować z '-ddump-core' i zobacz, co się stało. – fuz

Odpowiedz

2

Podejrzewam, że jest to efekt uboczny używania -auto-all, który hamuje wiele optymalizacji, które normalnie wykonywałby GHC, w tym inlining. Podejrzewam, że różnica w twojej wersji nie-polimorficznej wynika z faktu, że vx, i vz są definiowane przez składnię rekordów, a nie z powodu polimorfizmu (ale mogę się mylić w tej kwestii).

Zamiast używać -auto-all, spróbuj dodać listę eksportu do modułu i skompilować za pomocą "-auto" lub ręcznie ustawiając miejsca powstawania kosztów za pomocą pragmów SCC. Zwykle korzystam z pragm SCC, ponieważ często chcę ustawić je na let-bound, które -auto-all nie zrobi.

2

Nie mogłem wymyślić, jak dodawać komentarze do odpowiedzi, więc robię komentarze w tej odpowiedzi.

Po pierwsze, dziękuję za odpowiedzi.

FUZxxl: Próbowałem -ddump-core i otrzymałem komunikat o błędzie, że -ddump-core jest nierozpoznaną flagą. Być może miałeś na myśli -ddump-simpl, który zalecała książka Real World Haskell, ale obawiam się, że nie wiem, jak odczytać wynik. Zajrzałem do pliku wyjściowego dla "vx" itp., Ale nigdy ich nie widziałem. Chyba powinienem nauczyć się czytać rdzeń. Czy są jakieś dobre przewodniki dla tego?

John: Według GHC za flag reference documentation, jeśli czytam to poprawnie, zarówno -Auto i -Auto-all, mają dodać _scc_s do funkcji nie wyraźny rolkach. Aby zobaczyć, czy -auto będzie dla mnie działać, stworzyłem kolejny przypadek testowy, w którym kod Vec3 był w osobnym pliku/module, z wyeksportowanymi Vec3 (Vec3), vx, vy, vz i punkt. Zaimportowałem ten moduł do pliku Main.hs. Kompilując je za pomocą -auto, nadal widziałem vx, vy, vz w pliku .prof.

Re: Twój komentarz, że różnica może wynikać z rekordowym składni zamiast polimorfizmu, wierzę, że różnica jest bardziej prawdopodobne, ze względu na polimorfizm, bo kiedy zdefiniowane

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

vx, VY i VZ nadal pojawił się w pliku .prof.

Tad

+0

Powinieneś rozważyć użycie prawdziwego konta dla swoich pytań. Jeśli masz takie konto, możesz zostawić commoents najpierw na własne pytania, a następnie na wszystko, gdy twoja reputacja jest wystarczająco wysoka. – fuz

+0

Dzięki za poradę. Zrobiłem to teraz. – Tad