Two things: 1) Why aren't there built in Storable instances for tuples? Writing my own is a pain and in keeping with the 'up to 7tuple' limit, I think built in instances would be nice 2) Could someone tell me what 'alignment' is and if this is the correct definition of a storable tuple: instance (Storable a, Storable b) => Storable (a,b) where sizeOf (a,b) = sizeOf a + sizeOf b alignment (a,b) = alignment a + alignment b peek ptr = do a <- peek (castPtr ptr) b <- peek (castPtr ptr `plusPtr` sizeOf a) return (a,b) poke ptr (a,b) = do poke (castPtr ptr) a poke (castPtr ptr `plusPtr` sizeOf a) b -- Hal Daume III "Computer science is no more about computers | hdaume@isi.edu than astronomy is about telescopes." -Dijkstra | www.isi.edu/~hdaume
G'day all. On Mon, Aug 05, 2002 at 05:39:19PM -0700, Hal Daume III wrote:
2) Could someone tell me what 'alignment' is [...]
On many architectures, data must be stored at an address which is an integer multiple of some small number (often 2, 4 or 8, depending on the data and on the architecture). Even where it is not a requirement of the architecture, it's often faster to align data so that it does not require more than one bus cycle to fetch and/or store, and so that it doesn't span a cache line boundary. This number is called the "alignment", and a good rule of thumb for computing it is: instance Storable a where alignment a = sizeOf a `min` machine_word_size where machine_word size is 4 for 32-bit architectures, 8 for 64-bit architectures and so on. Note that the above formula may not work in some situations (e.g. when sizeOf a < machine_word_size but sizeOf a is not a power of 2, or when a is a strange machine-specific type, like a DMA buffer or a hardware page). In general, you just have to know what the alignment of some type is. Cheers, Andrew Bromage
Andrew J Bromage <ajb@spamcop.net> writes:
This number is called the "alignment", and a good rule of thumb for computing it is:
instance Storable a where alignment a = sizeOf a `min` machine_word_size
The way we calculate it in GHC and Hugs is: #define offsetof(ty,field) ((size_t)((char *)&((ty *)0)->field - (char *)(ty *)0)) print("%d", offsetof(struct { char c; $1 ty;},ty)); The simplest way of getting this value into some Haskell code is to use hsc2hs (comes with GHC). Something like this should do you: instance Storable Foo where alignment _ = #const offsetof(struct { char c; $1 foo_ty;} sizeOf _ = #const sizeof(foo_ty) peek = ... poke = ... See http://haskell.org/ghc/docs/latest/html/users_guide/hsc2hs.html for more info about hsc2hs. -- Alastair Reid alastair@reid-consulting-uk.ltd.uk Reid Consulting (UK) Limited http://www.reid-consulting-uk.ltd.uk/alastair/
On 06-Aug-2002, Alastair Reid <alastair@reid-consulting-uk.ltd.uk> wrote:
Andrew J Bromage <ajb@spamcop.net> writes:
This number is called the "alignment", and a good rule of thumb for computing it is:
instance Storable a where alignment a = sizeOf a `min` machine_word_size
The way we calculate it in GHC and Hugs is:
#define offsetof(ty,field) ((size_t)((char *)&((ty *)0)->field - (char *)(ty *)0))
You shouldn't define offsetof() yourself. The C standard provides offsetof() in <stdlib.h> -- you should use that rather than defining it yourself. Defining offsetof() yourself is an error if <stdlib.h> is included, because you are stepping on the implementation's namespace. Furthermore, the definition there is not standard-conforming C code, since it dereferences a null pointer. -- Fergus Henderson <fjh@cs.mu.oz.au> | "I have always known that the pursuit The University of Melbourne | of excellence is a lethal habit" WWW: <http://www.cs.mu.oz.au/~fjh> | -- the last words of T. S. Garp.
Hal Daume III wrote:
2) Could someone tell me what 'alignment' is
As the documentation says: Computes the alignment constraint of the argument. An alignment constraint x is fulfilled by any address divisible by x. The value of the argument is not used. E.g. an alignment of 2 means that the data must be stored at an even address, an alignment of 4 means that the data must be stored at an address which is a multiple of 4, etc.
and if this is the correct definition of a storable tuple:
Not really. [Disclaimer: sample code is off the top of my head, untested, supplied without warranty etc.]
instance (Storable a, Storable b) => Storable (a,b) where sizeOf (a,b) = sizeOf a + sizeOf b
You also need to allow for any padding which is required to satisfy the alignment constraints of b, e.g. sizeOf (a,b) = sizeOf a + padding (a,b) + sizeOf b where padding (a,b) = (alignment b - sizeOf a `mod` alignment b) `mod` alignment b
alignment (a,b) = alignment a + alignment b
The alignment of the overall structure is determined by the alignment of the first element. Subsequent elements are aligned (if necessary) by the addition of padding between elements. alignment (a,_) = alignment a
peek ptr = do a <- peek (castPtr ptr) b <- peek (castPtr ptr `plusPtr` sizeOf a) return (a,b)
Again, there may be padding between a and b, i.e.
b <- peek (castPtr ptr `plusPtr` (sizeOf a + padding (a,b)))
poke ptr (a,b) = do poke (castPtr ptr) a poke (castPtr ptr `plusPtr` sizeOf a) b
Ditto.
poke (castPtr ptr `plusPtr` (sizeOf a + padding (a,b))) b
-- Glynn Clements <glynn.clements@virgin.net>
participants (5)
-
Alastair Reid -
Andrew J Bromage -
Fergus Henderson -
Glynn Clements -
Hal Daume III