[Haskell-cafe] Re: MD5 performance optimizations, and GHC -via-C producing segfaulting binary

Don Stewart dons at galois.com
Tue May 20 16:13:14 EDT 2008


bulat.ziganshin:
> Hello Andrew,
> 
> Tuesday, May 20, 2008, 11:05:52 PM, you wrote:
> 
> >> -funbox-strict-fields.
> >>   
> 
> > I did try that, but it didn't seem to make any difference for me. [Maybe
> 
> it may be that ghc just not recompiled program when you supplied this
> switch. as i wrote, this switch by itself made your original program
> 1.5x faster on my box. try to delete .o/.exe before rebuilding
> 
> and, without this switch representation for !Int32 is the same as for
> Int32 - only difference is that when data is assigned to such field
> they are evaluated first (and then boxed)
> 
> it is not enabled by default, because for *non-primitive* datatypes
> such as B below automatic unboxing of strict fields of this type may
> decrease sharing and thus memory/performance. imagine for example:
> 
> data A = A !B !B
> data B = B !Int !Int !Int !Int !Int
> 
> b = B 1 1 1 1 1
> a = A b b
> 
> jhc automatically unboxes strict fields of primitive datatypes, which
> is guaranteed to provide only positive effects. may be somesay the
> same will be added to ghc

I'm confused. GHC of course unboxes strict fields of primitive data types.

    {-# OPTIONS -O2 -fvia-C -optc-O2 -funbox-strict-fields #-}

    data A = A !B !B
    data B = B !Int !Int !Int !Int !Int

    b = B 1 2 3 4 5
    a = A b b

    go :: Int -> A
    go 0 = a
    go n = go (n-1)

    main = print $ case go 10 of
               A (B a b c d e) (B a' b' c' d' e') -> a + b + c + d + e
                                                   + a' + b' + c' + d' + e'

For example, go compiles to:

        $wgo :: Int#
                     -> (# Int#,
                           Int#,
                           Int#,
                           Int#,
                           Int#,
                           Int#,
                           Int#,
                           Int#,
                           Int#,
                           Int# #)

        $wgo =
          \ (ww_svf :: Int#) ->
            case ww_svf of ds_Xmw {
              __DEFAULT -> $wgo (-# ds_Xmw 1);
              0 -> (# 1, 2, 3, 4, 5, 1, 2, 3, 4, 5 #)

Values are passed in registers, the structures are entirely unpacked into
registers or stack for return.

Were you not aware of this Bulat?

-- Don


More information about the Haskell-Cafe mailing list