Meaning of '!' in record defintion? UNPACK?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

Meaning of '!' in record defintion? UNPACK?

Erik de Castro Lopo-29
Hi all,

I'm looking at some code that defines a record:

    data Position =
           Position { posOffset :: {-# UNPACK #-} !Int
                    , posRow :: {-# UNPACK #-} !Int
                    , posColumn :: {-# UNPACK #-} !Int
                    }

What does the the exclamation mark mean? And UNPACK?

Thanks in advance.

Cheers,
Erik
--
-----------------------------------------------------------------
Erik de Castro Lopo
-----------------------------------------------------------------
Microsoft is finally bringing all of its Windows operating system families
under one roof. It will combine all of the features of CE, stability and
support of ME and the speed of NT.
It will be called Windows CEMENT...
Reply | Threaded
Open this post in threaded view
|

Meaning of '!' in record defintion? UNPACK?

Thomas Davie

On 26 Feb 2009, at 11:42, Erik de Castro Lopo wrote:

> Hi all,
>
> I'm looking at some code that defines a record:
>
>    data Position =
>           Position { posOffset :: {-# UNPACK #-} !Int
>                    , posRow :: {-# UNPACK #-} !Int
>                    , posColumn :: {-# UNPACK #-} !Int
>                    }
>
> What does the the exclamation mark mean? And UNPACK?

The ! means "strict" ? i.e. don't store a thunk for an Int here, but  
evaluate it first.

The {-# UNPACK #-} tells the compiler that it can unpack the Int ?  
meaning that a Position will be neatly packed into 12 bytes.

Bob
Reply | Threaded
Open this post in threaded view
|

Meaning of '!' in record defintion? UNPACK?

Colin Paul Adams
>>>>> "Thomas" == Thomas Davie <[hidden email]> writes:

    Thomas> The {-# UNPACK #-} tells the compiler that it can unpack
    Thomas> the Int ? meaning that a Position will be neatly packed
    Thomas> into 12 bytes.

What would be the difference if there was no UNPACK pragma?
--
Colin Adams
Preston Lancashire
Reply | Threaded
Open this post in threaded view
|

Meaning of '!' in record defintion? UNPACK?

Thomas Davie

On 26 Feb 2009, at 12:07, Colin Paul Adams wrote:

>>>>>> "Thomas" == Thomas Davie <[hidden email]> writes:
>
>    Thomas> The {-# UNPACK #-} tells the compiler that it can unpack
>    Thomas> the Int ? meaning that a Position will be neatly packed
>    Thomas> into 12 bytes.
>
> What would be the difference if there was no UNPACK pragma?

The tag in the Ints would be included in the structure created, with  
UNPACK, they would not.

Bob
Reply | Threaded
Open this post in threaded view
|

Meaning of '!' in record defintion? UNPACK?

Colin Paul Adams
>>>>> "Thomas" == Thomas Davie <[hidden email]> writes:

    Thomas> On 26 Feb 2009, at 12:07, Colin Paul Adams wrote:

>>>>>> "Thomas" == Thomas Davie <[hidden email]> writes:
    >>
    Thomas> The {-# UNPACK #-} tells the compiler that it can unpack
    Thomas> the Int ? meaning that a Position will be neatly packed
    Thomas> into 12 bytes.
    >>
    >> What would be the difference if there was no UNPACK pragma?

    Thomas> The tag in the Ints would be included in the structure
    Thomas> created, with UNPACK, they would not.

What is the tag?
--
Colin Adams
Preston Lancashire
Reply | Threaded
Open this post in threaded view
|

Meaning of '!' in record defintion? UNPACK?

Felipe Lessa
In reply to this post by Colin Paul Adams
On Thu, Feb 26, 2009 at 8:07 AM, Colin Paul Adams
<[hidden email]> wrote:
>>>>>> "Thomas" == Thomas Davie <[hidden email]> writes:
>
> ? ?Thomas> The {-# UNPACK #-} tells the compiler that it can unpack
> ? ?Thomas> the Int ? meaning that a Position will be neatly packed
> ? ?Thomas> into 12 bytes.
>
> What would be the difference if there was no UNPACK pragma?

For example, if you write

valid :: Position -> Bool
valid (Position o r c) = o < r && c < 80

It is just an example, not necessarily meaningful :). If you use the
UNPACK pragmas, then internally the compiler will create something
like

valid :: Int# -> Int# -> Int# -> Bool
valid o r c = o <# r && c <# 80

Basically the three integers will be passed on registers. Without the
UNPACK, they would be passed on the heap. Without the strictness
annotation, a pointer on the heap would be passed to them (i.e. a
pointer on the register would point to the Position structure which
would have a pointer to the integer, not very nice).

HTH,

PS: I'm not sure if the unboxed operations I wrote are correct, but
you get the idea :).

--
Felipe.
Reply | Threaded
Open this post in threaded view
|

Meaning of '!' in record defintion? UNPACK?

Daniel Fischer-4
In reply to this post by Colin Paul Adams
Am Donnerstag, 26. Februar 2009 12:07 schrieb Colin Paul Adams:
> >>>>> "Thomas" == Thomas Davie <[hidden email]> writes:
>
>     Thomas> The {-# UNPACK #-} tells the compiler that it can unpack
>     Thomas> the Int ? meaning that a Position will be neatly packed
>     Thomas> into 12 bytes.
>
> What would be the difference if there was no UNPACK pragma?

Section 8.12.10 of the users' guide says:
"The UNPACK indicates to the compiler that it should unpack the contents of a
constructor field into the constructor itself, removing a level of
indirection."

It has more, and also says when it's not a good idea to use it.

Int is defined as

data Int = I# Int#

where Int# is a raw machine int. If you use the {-# UNPACK #-} pragma, you
tell GHC that you'd very much like Position to be stored as constructor +
three contiguous raw machine integers. Mostly, it will do so.
If you don't use the pragma, i.e. have

    data Position =
           Position { posOffset :: !Int
                    , posRow :: !Int
                    , posColumn :: !Int
                    }

, GHC may or may not decide to store it thus, with -O2 it's not too unlikely,
I think. But it's also not unlikely that it will be stored as constructor +
three pointers to three evaluated Ints, which is much better than pointers to
thunks, but not as good as having the raw values directly by the constructor.

Cheers,
Daniel
Reply | Threaded
Open this post in threaded view
|

Meaning of '!' in record defintion? UNPACK?

Magnus Therning
On Thu, Feb 26, 2009 at 11:33 AM, Daniel Fischer
<[hidden email]> wrote:

> Am Donnerstag, 26. Februar 2009 12:07 schrieb Colin Paul Adams:
>> >>>>> "Thomas" == Thomas Davie <[hidden email]> writes:
>>
>> ? ? Thomas> The {-# UNPACK #-} tells the compiler that it can unpack
>> ? ? Thomas> the Int ? meaning that a Position will be neatly packed
>> ? ? Thomas> into 12 bytes.
>>
>> What would be the difference if there was no UNPACK pragma?
>
> Section 8.12.10 of the users' guide says:
> "The UNPACK indicates to the compiler that it should unpack the contents of a
> constructor field into the constructor itself, removing a level of
> indirection."
>
> It has more, and also says when it's not a good idea to use it.
>
> Int is defined as
>
> data Int = I# Int#
>
> where Int# is a raw machine int. If you use the {-# UNPACK #-} pragma, you
> tell GHC that you'd very much like Position to be stored as constructor +
> three contiguous raw machine integers. Mostly, it will do so.
> If you don't use the pragma, i.e. have
>
> ? ?data Position =
> ? ? ? ? ? Position { posOffset :: !Int
> ? ? ? ? ? ? ? ? ? ?, posRow :: !Int
> ? ? ? ? ? ? ? ? ? ?, posColumn :: !Int
> ? ? ? ? ? ? ? ? ? ?}
>
> , GHC may or may not decide to store it thus, with -O2 it's not too unlikely,
> I think. But it's also not unlikely that it will be stored as constructor +
> three pointers to three evaluated Ints, which is much better than pointers to
> thunks, but not as good as having the raw values directly by the constructor.
>
> Cheers,
> Daniel
> _______________________________________________
> Beginners mailing list
> [hidden email]
> http://www.haskell.org/mailman/listinfo/beginners
>

Are there any guarantees here, or is it just me telling the compiler
to please do what I say, but the compiler can decide not to follow my
wishes?
Is address aligning predictable?

I'm basically wondering if it'd be possible to to use this mechanism
to avoid using FFI when reading data that basically is a dump of
structs in a C program.

/M

--
Magnus Therning                        (OpenPGP: 0xAB4DFBA4)
magnus?therning?org          Jabber: magnus?therning?org
http://therning.org/magnus         identi.ca|twitter: magthe
Reply | Threaded
Open this post in threaded view
|

Meaning of '!' in record defintion? UNPACK?

Daniel Fischer-4
Am Donnerstag, 26. Februar 2009 12:36 schrieb Magnus Therning:
> Are there any guarantees here, or is it just me telling the compiler
> to please do what I say, but the compiler can decide not to follow my
> wishes?

I don't think there are guarantees, as the section ends with:

"If a field cannot be unpacked, you will not get a warning, so it might be an
idea to check the generated code with -ddump-simpl.

See also the -funbox-strict-fields flag, which essentially has the effect of
adding {-# UNPACK #-} to every strict constructor field."

But it should be very likely to do what you want (of course, always compile
with -O or -O2).

> Is address aligning predictable?

Absolutely no idea, sorry.

>
> I'm basically wondering if it'd be possible to to use this mechanism
> to avoid using FFI when reading data that basically is a dump of
> structs in a C program.

I doubt it, as I understand it, with {-# UNPACK #-}, you'll have the layout

constuctor rawdata

and the C structs won't have the constructor.

>
> /M

Cheers,
Daniel