Page 3 of 39. Page 3 of 39. introduction-to-haskell-optimization.pdf. introduction-to-haskell-optimization.pdf. Open. Ex
Introduction to Low Level Haskell Optimization Dan Doel (
[email protected])
September 17, 2014
How to Optimize
How to Optimize
I
Make sure you’re using -O(2)
How to Optimize
I I
Make sure you’re using -O(2) Profile
How to Optimize
I I I
Make sure you’re using -O(2) Profile Use the best algorithm
How to Optimize
I I I I
Make sure you’re using -O(2) Profile Use the best algorithm Implement it in the most efficient way
Getting Intermediate Compiler Information
Getting Intermediate Compiler Information GHC user guide section 4.19: -ddump-*
Getting Intermediate Compiler Information GHC user guide section 4.19: -ddump-* -ddump-simpl
Getting Intermediate Compiler Information GHC user guide section 4.19: -ddump-* -ddump-simpl -ddump-stg
Getting Intermediate Compiler Information GHC user guide section 4.19: -ddump-* -ddump-simpl -ddump-stg -ddump-cmm -ddump-asm -ddump-llvm
Getting Intermediate Compiler Information GHC user guide section 4.19: -ddump-* -ddump-simpl -ddump-stg -ddump-cmm -ddump-asm -ddump-llvm -ddump-to-file
STG Syntax
STG Syntax: Basic
literal := 0 | 1 | ... atom := var | literal atoms := {atom, ..., atom} vars := {var, ..., var} prim := +# | *# | ...
STG Syntax: Bindings
bindings := binding ; ... ; binding binding := var = lambdaForm lambdaForm := vars \pi vars -> expr pi := u | n
STG Syntax: Expressions expr := | | | | | |
let bindings in expr letrec bindings in expr case expr of var { alts } var atoms constructor atoms prim atoms literal
alts := aalts | palts aalts := aalt ; ... ; aalt ; default palts := palt ; ... ; palt ; default aalt := constr vars -> expr palt := literal -> expr default := _DEFAULT_ -> expr
Operation
Operation: application is tail call
f {x, y, z}
Operation: application is tail call
f {x, y, z} : {x, xs}
Operation: case uses stack
case e of v { ... }
Operation: case always evaluates
seq = {} \n {x, y} -> case x of _ { _DEFAULT_ -> y }
Operation: let is allocation
let { v1 = {w, x} \n {y, z} -> ... ; v2 = {w} \n {y} -> ... } in ...
Operation: calling a constructor is allocation
f = {} \n {i} -> case +# i 1 of j { _DEFAULT_ -> I# j }
Operation: unboxed types
Int#, Word#, Double#, Float#, Char#, (# a, b #), ...
Operation: unboxed types
Int#, Word#, Double#, Float#, Char#, (# a, b #), ...
I
Important for avoiding allocation
Examples
Example: map (version 1)
map f [ ] = [] map f (y:ys) = f y : map f ys
Example: map (version 1)
map f [ ] = [] map f (y:ys) = f y : map f ys map = {} \n {f, xs} -> case xs of _ { [] {} -> [] {} ; : {y,ys} -> let { fy = {f,y} \u {} -> f {y} ; mfys = {f,ys} \u {} -> map {f,ys} } in : {fy, mfys} }
Example: map (version 2) map f = go where go [ ] = [] go (y:ys) = f y : go ys
Example: map (version 2) map f = go where go [ ] = [] go (y:ys) = f y : go ys map = {} \n {f} -> letrec { go = {f, go} \n {xs} -> case xs of _ { [] {} -> [] {} ; : {y,ys} -> let { fy = {f,y} \u {} -> f {y} ; goys = {go,ys} \u -> go {ys} } in : {fy, goys} } } in go
Tools
Tools I
Bang patterns
Tools I
Bang patterns {-# LANGUAGE BangPatterns #-} foo !x y = ...
Tools I
Bang patterns {-# LANGUAGE BangPatterns #-} foo !x y = ...
I
Pragmas
Tools I
Bang patterns {-# LANGUAGE BangPatterns #-} foo !x y = ...
I
Pragmas {-# INLINE foo #-}
Tools I
Bang patterns {-# LANGUAGE BangPatterns #-} foo !x y = ...
I
Pragmas {-# INLINE foo #-} {-# SPECIALIZE foo :: Int -> Int #-}
Tools I
Bang patterns {-# LANGUAGE BangPatterns #-} foo !x y = ...
I
Pragmas {-# INLINE foo #-} {-# SPECIALIZE foo :: Int -> Int #-} {-# INLINABLE foo #-}
Resources
Resources
I
GHC user guide I
I
STG Paper I
I
research.microsoft.com/apps/pubs/default.aspx?id=67083
GHC core syntax highlighting for vim I
I
haskell.org/ghc/docs/latest/html/users guide/index.html
hub.darcs.net/dolio/vim-ghc-core
These slides and examples I
hub.darcs.net/dolio/optimization-talk-demo