[Haskell-cafe] More good performance results for ghc 6.8

Jon Harrop jon at ffconsultancy.com
Wed Nov 14 04:31:56 EST 2007


On Wednesday 14 November 2007 00:14, Don Stewart wrote:
> Trying out some of the great language shootout programs with ghc 6.8 is
> producing nice results. For example, our "classic" cache-hammering,
> bitwise sieve benchmark is out of the box 10% faster with the new
> compiler. The (already rather good) benchmark is here (the
> same speed as the OCaml version under ghc 6.6):
>
>    
> http://shootout.alioth.debian.org/gp4/benchmark.php?test=nsievebits&lang=al
>l
>
> And timing with old and new ghc:
>
>     ghc 6.6.1
>         Primes up to 81920000  4774995
>         Primes up to 40960000  2488465
>         Primes up to 20480000  1299069
>         ./A66 13  4.50s user 0.02s system 100% cpu 4.515 total
>
>     ghc 6.8.1
>         Primes up to 81920000  4774995
>         Primes up to 40960000  2488465
>         Primes up to 20480000  1299069
>         ./A68 13  4.13s user 0.01s system 99% cpu 4.142 total
>
> Lovely work GHC HQ, when low level, highly tuned code like this gets
> magically faster!  Once 6.8 is in Gentoo (or earlier...) we should see
> similar improvements across a range of shootout programs.

I get slightly different results on our 2.2GHz Athlon64 X2 machines but they 
are only up to 20% slower than C++ for OCaml and Haskell:

F# 1.9.2.9: 2.125s on 32-bit Windows XP
GHC 6.8:    1.414s on 64-bit Debian Lenny
GHC 6.6:    1.387s on 64-bit Debian Lenny
OCaml 3.10: 1.278s on 64-bit Debian Lenny
g++ 4.2.3:  1.176s on 64-bit Debian Lenny

Interestingly, GHC 6.8 does not improve over GHC 6.6 on this machine. 
Regardless, the performance in absolute terms is incredible (IMHO).

Also, I took the liberty of optimizing the OCaml:

open Printf
open Bigarray

let rec clear (a : (int, int8_unsigned_elt, c_layout) Bigarray.Array1.t) n i =
  let j = ref (2 * i) in
  while !j <= n do
    let ic = !j lsr 3 in
    let bit = a.{ic} land lnot(1 lsl (!j land 0x7)) in
    if a.{ic} <> bit then a.{ic} <- bit;
    j := !j + i
  done

let nsieve n =
  let a = Array1.create int8_unsigned c_layout ((n lsr 3) + 2) in
  Array1.fill a 0xFF;
  let count = ref 0 in
  for i = 2 to n do
    if a.{i lsr 3} land (1 lsl (i land 0x7)) > 0 then begin
      incr count;
      if i*i <= n then clear a n i
    end
  done;
  !count

let test n = printf "Primes up to %8i %8i\n%!" n (nsieve n)

let () = match Sys.argv with
  | [|_; n|] ->
      let n = int_of_string n in
      List.iter (fun n -> if n>0 then test ((1 lsl n) * 10000)) [n; n-1; n-2]
  | _ -> printf "Usage: ./sieve <n>\n%!"

-- 
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/products/?e


More information about the Haskell-Cafe mailing list