Basically I have a simple function call, which when used in conjunction with Criterion, results in the memory consumption exploding.
Suppose I have the following program :
{-# OPTIONS_GHC -fno-cse #-}
{-# LANGUAGE BangPatterns #-}
module Main where
import Criterion.Main
import Data.List
num :: Int
num = 10000000
lst :: a -> [Int]
lst _ = [1,2..num]
myadd :: Int -> Int -> Int
myadd !x !y = let !result = x + y in
result
mysum = foldl' myadd 0
main :: IO ()
main = do
print $ mysum (lst ())
Then this program (compiled with O0) runs fine, without the memory exploding.
If we use cabal build -v
to yield a dump of the compilation
commands invoked, and then tag -ddump-simpl -fforce-recomp -O0 -dsuppress-all
(suggested in IO/Monadic assign operator causing ghci to explode for infinite list) to the end of the ghc --make -no-link ...
command, we get the following core :
num
num = I# 10000000
lst
lst = \ @ a_a3Yn _ -> enumFromThenTo $fEnumInt (I# 1) (I# 2) num
myadd
myadd =
\ x_a3Cx y_a3Cy ->
case x_a3Cx of x1_X3CC { I# ipv_s4gX ->
case y_a3Cy of y1_X3CE { I# ipv1_s4h0 ->
+ $fNumInt x1_X3CC y1_X3CE
}
}
mysum
mysum = foldl' myadd (I# 0)
main
main =
print
$fShowInt (mysum (enumFromThenTo $fEnumInt (I# 1) (I# 2) num))
main
main = runMainIO main
It seems that no CAFs are being produced, which is consistent with the fact that the program does not explode. Now if I run the following program which uses criterion 1.1.0.0 :
{-# OPTIONS_GHC -fno-cse #-}
{-# LANGUAGE BangPatterns #-}
module Main where
import Criterion.Main
import Data.List
num :: Int
num = 10000000
lst :: a -> [Int]
lst _ = [1,2..num]
myadd :: Int -> Int -> Int
myadd !x !y = let !result = x + y in
result
mysum = foldl' myadd 0
main :: IO ()
main = defaultMain [
bgroup "summation"
[bench "mysum" $ whnf mysum (lst ())]
]
then the memory consumption explodes. However printing the core yields :
num
num = I# 10000000
lst
lst = \ @ a_a3UV _ -> enumFromThenTo $fEnumInt (I# 1) (I# 2) num
myadd
myadd =
\ x_a3Cx y_a3Cy ->
case x_a3Cx of x1_X3CC { I# ipv_s461 ->
case y_a3Cy of y1_X3CE { I# ipv1_s464 ->
+ $fNumInt x1_X3CC y1_X3CE
}
}
mysum
mysum = foldl' myadd (I# 0)
main
main =
defaultMain
(: (bgroup
(unpackCString# "summation"#)
(: (bench
(unpackCString# "mysum"#)
(whnf mysum (enumFromThenTo $fEnumInt (I# 1) (I# 2) num)))
([])))
([]))
main
main = runMainIO main
and it seems that no CAFs are being produced. Therefore why does the latter program, which uses criterion, result in the memory consumption exploding, whereas the former program does not? I am using GHC version 7.8.3