Ticket #6111 (closed bug: fixed)
Simple loop performance regression of 7.4.1 relative to 7.0.4
| Reported by: | mdgabriel | Owned by: | igloo |
|---|---|---|---|
| Priority: | normal | Milestone: | |
| Component: | Compiler | Version: | 7.4.1 |
| Keywords: | Loop performance regression | Cc: | |
| Operating System: | Linux | Architecture: | x86 |
| Type of failure: | Runtime performance bug | Difficulty: | Unknown |
| Test Case: | IntegerConversionRules | Blocked By: | |
| Blocking: | Related Tickets: | #6110 |
Description
Problem
Severe simple loop performance regression in 7.4.1 relative to 7.0.4:
(Loop GHC 7.4.1)/(Loop GHC 7.0.4) ~ 2.9
System
GNU/Linux 3.2.0-24-generic Ubuntu i386
Compilers
GHC 7.0.4
GHC 7.4.1
GCC 4.6.3 for a baseline
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
7.4.1
ghc -O2 -Wall --make -o add Main.hs
ghc --version
7.0.4
ghc -O2 -Wall --make -o add Main.hs
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
4.6.3
gcc -O2 -Wall cadd.c -o cadd
Data: time add-7.0.4 n
n seconds
100000000 0.77
200000000 1.55
300000000 2.33
400000000 3.11
500000000 3.89
600000000 4.66
700000000 5.45
800000000 6.21
900000000 6.99
1000000000 7.77
Data: time add-7.4.1 n
n seconds
100000000 2.26
200000000 4.54
300000000 6.82
400000000 9.08
500000000 11.33
600000000 13.64
700000000 15.91
800000000 18.20
900000000 20.43
1000000000 22.76
Data: time cadd-4.6.3 n
n seconds
100000000 1.04
200000000 2.10
300000000 3.12
400000000 4.19
500000000 5.23
600000000 6.26
700000000 7.32
800000000 8.37
900000000 9.41
1000000000 10.45
Linear in n
y is in seconds
GHC 7.0.4: y = (0.78/108) * n - 0.02
GCC 4.6.3: y = (1.04/108) * n + 0.03
GHC 7.4.1: y = (2.28/108) * n - 0.04
Severe performance regression:
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.
