Simple loop performance regression of 7.4.1 relative to 7.0.4
Problem
Severe simple loop performance regression in 7.4.1 relative to 7.0.4:[[BR]] (Loop GHC 7.4.1)/(Loop GHC 7.0.4) ~ 2.9
System
GNU/Linux 3.2.0-24-generic Ubuntu i386[[BR]]
Compilers
GHC 7.0.4[[BR]] GHC 7.4.1[[BR]] GCC 4.6.3 for a baseline[[BR]]
Add.hs
module Main where
import Foreign.Storable (sizeOf)
import System.Environment (getArgs)
main :: IO ()
main = do args <- getArgs
if length args == 1
then putAdd (read (head args) :: Int)
else error "need a count operand"
putAdd :: Int -> IO ()
putAdd cnt = let s = loop 0 cnt (0 :: Double)
d = sizeOf (0 :: Double)
in putStrLn ("Add="++show s++" (sizeOf(Double)="++show d++")")
loop :: (Integral a, Num b) => a -> a -> b -> b
loop i n t = if i < n
then loop (succ i) n (t + fromIntegral i)
else t
GHC compilation
ghc --version[[BR]]
- 4.1[[BR]]
ghc -O2 -Wall --make -o add Main.hs[[BR]]
[[BR]]
ghc --version[[BR]]
- 0.4[[BR]]
ghc -O2 -Wall --make -o add Main.hs[[BR]]
Baseline cadd.c
#include <libgen.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
unsigned long i, size;
double tot=0;
if (argc != 2)
{
(void)fprintf(stderr, "usage: %s size\n", basename(argv[0]));
return(1);
}
size = atol(argv[1]);
for(i = 0; i < size; i++) tot += (double)i;
(void)printf("Add=%.15e\n", tot);
return(0);
}
GCC baseline compilation
gcc --version[[BR]]
- 6.3[[BR]]
gcc -O2 -Wall cadd.c -o cadd[[BR]]
Data: time add-7.0.4 n
n seconds[[BR]] 100000000 0.77[[BR]] 200000000 1.55[[BR]] 300000000 2.33[[BR]] 400000000 3.11[[BR]] 500000000 3.89[[BR]] 600000000 4.66[[BR]] 700000000 5.45[[BR]] 800000000 6.21[[BR]] 900000000 6.99[[BR]] 1000000000 7.77[[BR]]
Data: time add-7.4.1 n
n seconds[[BR]] 100000000 2.26[[BR]] 200000000 4.54[[BR]] 300000000 6.82[[BR]] 400000000 9.08[[BR]] 500000000 11.33[[BR]] 600000000 13.64[[BR]] 700000000 15.91[[BR]] 800000000 18.20[[BR]] 900000000 20.43[[BR]] 1000000000 22.76[[BR]]
Data: time cadd-4.6.3 n
n seconds[[BR]] 100000000 1.04[[BR]] 200000000 2.10[[BR]] 300000000 3.12[[BR]] 400000000 4.19[[BR]] 500000000 5.23[[BR]] 600000000 6.26[[BR]] 700000000 7.32[[BR]] 800000000 8.37[[BR]] 900000000 9.41[[BR]] 1000000000 10.45[[BR]]
Linear in n
y is in seconds[[BR]] [[BR]] GHC 7.0.4: y = (0.78/10^8) * n - 0.02[[BR]] GCC 4.6.3: y = (1.04/10^8) * n + 0.03[[BR]] GHC 7.4.1: y = (2.28/10^8) * n - 0.04[[BR]]
Severe performance regression:[[BR]] GHC 7.4.1/GHC 7.0.4 ~ 2.28/0.78 ~ 2.9
Notes
1/ I discovered the problem in a slightly more complicated case when I recompiled a package that used Data.Vector.Unboxed.
2/ I am impressed that the GHC 7.0.4 is faster than the GCC 4.6.3. I expected it to be close, but not faster. Given this impressive result, I certainly would hope that the same result can be recovered once again.
Trac metadata
Trac field | Value |
---|---|
Version | 7.4.1 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |