2011-01-13 5 views
5

J'essaie de comprendre comment optimiser du code. Ici, il est:fonctions inlined apparaissent toujours dans le fichier .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 

Quand je compilez avec GHC 6.12.1 (linux ubuntu sur une machine i486)

GHC --make -O2 Vec.hs -Prof -auto -Toutes -fforce-ReComp

et exécuter

Vec + RTS -p

En regardant le fichier 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 

Je vois que la fonction Vx et Vy prennent une part importante du temps.

Pourquoi est-ce? Je pensais que le pragma SPECIALIZE INLINE ferait ces fonctions disparaissent.

Lorsque vous utilisez un non polymorphes

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

les fonctions vx, vy, vz ne montrent pas comme un centre de coûts.

+1

Avez-vous réellement regardé core? Essayez de compiler avec '-ddump-core' et voyez, ce qui s'est passé. – fuz

Répondre

2

Je suppose qu'il s'agit d'un effet secondaire de l'utilisation de -auto-all, ce qui inhibe de nombreuses optimisations GHC devrait normalement effectuer, y compris inline. Je soupçonne que la différence dans votre version non polymorphe est en fait due à vx, vy, et vz étant défini via la syntaxe d'enregistrement plutôt qu'à cause du polymorphisme (mais je pourrais me tromper à ce sujet). Au lieu d'utiliser -auto-all, essayez d'ajouter une liste d'exportation au module et de compiler avec "-auto", ou de définir manuellement les centres de coûts via des pragmas SCC. J'utilise généralement des pragmas SCC de toute façon parce que je veux souvent les mettre sur des fonctions de let-bound, ce que -auto-tout ne fera pas.

2

Je ne pouvais pas comprendre comment faire des commentaires aux réponses, donc je fais des commentaires dans cette réponse.

D'abord, merci pour vos réponses.

FUZxxl: J'ai essayé -ddump-core, et j'ai reçu un message d'erreur indiquant que -ddump-core était un indicateur non reconnu. Peut-être que vous vouliez dire -ddump-simpl, que le livre Real World Haskell recommandait d'utiliser, mais j'ai peur de ne pas savoir lire la sortie. J'ai regardé dans le fichier de sortie pour "vx", etc, mais ne les ai jamais vus. Je suppose que je devrais apprendre à lire le noyau. Y a-t-il de bons guides pour ça?

John: Selon flag reference documentation de GHC, si je lis correctement, à la fois -auto et -auto-tout, sont censés ajouter _scc_s aux fonctions pas INLINE marquée. Pour voir si -auto fonctionnerait pour moi, j'ai créé un autre cas de test dans lequel le code Vec3 se trouvait dans un fichier/module séparé, avec Vec3 (Vec3), vx, vy, vz et point exportés. J'ai importé ce module dans un fichier Main.hs. En les compilant avec -auto, j'ai toujours vu vx, vy, vz dans le fichier .prof.

Re: commentaire que la différence pourrait être due à la syntaxe des enregistrements au lieu de polymorphisme, je crois que la différence est plus probable en raison de polymorphisme, parce que quand je définissais

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

vx, Vy et vz encore montré dans le fichier .prof.

Tad

+0

Vous devriez envisager d'utiliser un compte réel pour vos questions. Si vous disposez d'un tel compte, vous pouvez laisser vos questions en premier à vos propres questions et ensuite à n'importe quoi lorsque votre réputation est suffisamment élevée. – fuz

+0

Merci pour le conseil. Je l'ai fait maintenant. – Tad

Questions connexes