Unpack primitive types by default in data

Simon Marlow marlowsd at gmail.com
Thu Mar 1 09:41:25 CET 2012

On 29/02/2012 16:17, Johan Tibell wrote:
> On Wed, Feb 29, 2012 at 2:08 AM, Simon Marlow <marlowsd at gmail.com
> <mailto:marlowsd at gmail.com>> wrote:
>     (I think you meant "record", not "field" in the last sentence, right?)
> I did mean record, but I wasn't being very clear. Let me try again.
>     It's not obvious to me why having a mixture of strict and nonstrict
>     (maybe you meant UNPACKed and not UNPACKed?) fields would make
>     things worse.  Could you give a concrete example?
> Sure. Lets say we have a value x of type Int, that we copy from
> constructor to constructor:
>      f (C_i x) = C_j x  -- for lots of different i:s and j:s
> (In practice C_i and C_j most likely have different types.)
> In a program with constructors, C_1 .. C_n, we can do one of three things:
>   1. Unpack no fields.
>   2. Unpack some fields.
>   3. Unpack all fields.
> Now, if we have a program that's currently in state (1) and we move to
> state (2) by manually adding some unpack pragmas, performance might get
> worse, as we introduce re-boxing where there was none before. However,
> if we kept unpacking fields until we got into state (3), performance
> might be even better than in state (1), because we are again back into a
> state where
>   * there's no reboxing (lazy functions aside), but
>   * we have better cache locality.
> I suspect many large Haskell programs (GHC included) are in state (1) or
> (2).

I think you're right, but in general there's no way to get to state (3) 
because C_j is often a constructor in a library, or a polymorphic 
constructor ((:) being a common case, I expect).  Furthermore C_j is 
often not a constructor - just passing x to a non-strict function is 
enough.  The larger and more complicated the code, the more likely it is 
that cases like this occur, and the harder it is to find them all and 
squash them (and even if you did so, maintaining the codebase in that 
state is very difficult).

> If we introduce -funbox-primtive-fields and turn it on by default, the
> hope would be that many programs go from (1) to (3), but that only works
> if the programs have consistently made primitive fields strict (or kept
> them all lazy, in which case -funbox-primitive-fields does nothing.) If
> the programmer have been inconsistent in his/her use of strictness
> annotations, we might end up in (2) instead.

Right, but I'm suggesting we'll end up in (2) for other reasons beyond 
our control.  How often this happens in practice, I don't know.


> Did this make any more sense?
> Cheers,
>    Johan

More information about the Glasgow-haskell-users mailing list