[Haskell-cafe] Very fast loops. Now!

Donald Bruce Stewart dons at cse.unsw.edu.au
Sat Feb 10 11:45:33 EST 2007


dons:
> The following C program was described on #haskell
> 
>     #include <stdio.h>
> 
>     int main()
>     {
>         double x = 1.0/3.0;
>         double y = 3.0;
>         int i    = 1;
>         for (; i<=1000000000; i++) {
>             x = x*y/3.0;
>             y = x*9.0;
>         }
>         printf("%f\n", x+y);
>     }
> 
> 
> Which was translated to the following Haskell:
> 
>     {-# OPTIONS -fexcess-precision #-}
> 
>     import Text.Printf
> 
>     main = go (1/3) 3 1
> 
>     go :: Double -> Double -> Int -> IO ()
>     go !x !y !i
>         | i == 1000000000 = printf "%f\n" (x+y)
>         | otherwise       = go (x*y/3) (x*9) (i+1)
> 
> 
> To everyone's surprise, GHC 6.6 beats GCC (3.3.5) here, at least the two test machines:
> 
> 
>     $ ghc -O -fexcess-precision -fbang-patterns -optc-O3 -optc-ffast-math -optc-mfpmath=sse -optc-msse2 A.hs -o a
> 
>     $ time ./a
>     3.333333
>     ./a  0.96s user 0.01s system 99% cpu 0.969 total
>                                          ^^^^^
> 
> Versus gcc 3.3.5:
> 
>     $ gcc -O3 -ffast-math -mfpmath=sse -msse2 -std=c99 t.c -o c_loop
>     $ time ./c_loop 
>     3.333333
>     ./c_loop  1.01s user 0.01s system 97% cpu 1.046 total
>                                               ^^^^^
> 
> Note that newer gcc's will statically compute that loop. Note also that
> -fexcess-precision must currently be provided as a pragma only.
> 
> I declare GHC Haskell numerics (with -fexcess-precision) not so shabby!
> 


GCC 4.x seems to do a much better job, turning the inner loop into:

    .L2:
        mulsd   %xmm3, %xmm0
        mulsd   %xmm1, %xmm0
        movapd  %xmm0, %xmm1
        mulsd   %xmm2, %xmm1
        addl    $1, %eax
        cmpl    $100000001, %eax
        jne .L2

-- Don


More information about the Haskell-Cafe mailing list