Strictness in data declaration not matched in assembler?
Tyson Whitehead
twhitehead at gmail.com
Thu Oct 16 11:49:02 EDT 2008
On Thursday 16 October 2008 07:03:05 Roman Leshchinskiy wrote:
> On 16/10/2008, at 21:34, Simon Peyton-Jones wrote:
> > BUT people who care probably UNPACK their strict fields too, which
> > is even better. The time you can't do that is for sum types
> > data T = MkT ![Int]
>
> You also can't do it for polymorphic components. I've used code like:
>
> data T a = MkT !a
>
> foo :: T (a,b) -> a
> foo (MkT (x,y)) = x
>
> Here, unpacking doesn't work but foo could still access the components
> of the pair directly.
This is actually the situation I was originally looking at. I just simplified
it for the sake of posting readable core and assembler.
Specifically, I was looking at some of the assembler GHC was generating for
some array code to see if it could do a clean enough job to be used instead of
C, and was finding this sort of thing because STUArrau is defined as
data STUArray s i a = STUArray !i !i !Int (MutableByteArray# s)
I also seem to recall seeing the same sort of thing in some of the state code
I was also looking at because STRep is defined as
type STRep s a = State# s -> (# State# s, a #)
(the a being the issue here).
With regard to cost, it is probably not that representative, but a typical
code path for the toy example I posted earlier goes from
leaq -8(%rbp),%rax
cmpq %r14,%rax
-- not taken jump -- (stack overflow check passed)
movq %rsi,%rbx
movq $sni_info,-8(%rbp)
addq $-8,%rbp
testq $7,%rbx
-- taken jump -- (x argument had already been forced)
movq 7(%rbx),%rbx
movq $snj_info,(%rbp)
testq $7,%rbx
-- taken jump -- (strict constructor argument is already forced)
cmpq $1,7(%rbx)
-- not taken jump -- (first of the case options)
movl $Main_lvl_closure+1,%ebx
addq $8,%rbp
jmp *(%rbp)
to
leaq -8(%rbp),%rax
cmpq %r14,%rax
-- not taken jump -- (stack overflow check passed)
movq %rsi,%rbx
movq $sni_info,-8(%rbp)
addq $-8,%rbp
testq $7,%rbx
-- taken jump -- (x argument has already been forced)
movq 7(%rbx),%rbx
cmpq $1,7(%rbx)
-- not taken jump -- (first of the case options)
movl $Main_lvl_closure+1,%ebx
addq $8,%rbp
jmp *(%rbp)
which is a 22% reduction (18 to 14) in instructions executed in the entire
function, or a 40% reduction (10 to 6) in instruction executed in the core of
the function (i.e., after the function's argument is possibly forced).
Cheers! -Tyson
PS: Thanks everyone for the very informative and interesting discussion.
More information about the Glasgow-haskell-users
mailing list