Boxed foreign prim
Simon Marlow
marlowsd at gmail.com
Mon Mar 12 11:45:39 CET 2012
On 09/03/2012 04:12, Edward Kmett wrote:
> I'm currently working with a lot of very short arrays of fixed length
> and as a thought experiment I thought I would try to play with fast
> numeric field accessors
>
> In particular, I'd like to use something like foreign prim to do
> something like
>
> > foreign import prim "cmm_getField" unsafeField# :: a -> Int# -> b
>
> > unsafeField :: a -> Int -> b
> > unsafeField a (I# i) = a' `pseq` unsafeField# a' i -- the pseq could
> be moved into the prim, I suppose.
> > where a' = unsafeCoerce a
>
> > fst :: (a,b) -> a
> > fst = unsafeField 0
>
> > snd :: (a,b) -> b
> > snd = unsafeField 1
>
> This becomes more reasonable to consider when you are forced to make
> something like
>
> > data V4 a = V4 a a a a
>
> using
>
> > unsafeIndex (V4 a _ _ _) 0 = a
> > unsafeIndex (V4 _ b _ _) 1 = b
> > unsafeIndex (V4 _ _ c _) 2 = c
> > unsafeIndex (V4 _ _ _ d) 3 = d
>
> rather than
>
> > unsafeIndex :: V4 a -> Int -> a
> > unsafeIndex = unsafeField
>
> But I can only pass unboxed types to foreign prim.
>
> Is this an intrinsic limitation or just an artifact of the use cases
> that have presented themselves to date?
It's an intrinsic limitation - the I# box is handled entirely at the
Haskell level, primitives only deal with primitive types.
But anyway, I suspect your first definition of unsafeIndex will be
faster than the one using foreign import prim, because calling
out-of-line to do the indexing is slow. Also pseq is slow - use seq
instead.
what you really want is built-in support for unsafeField#, which is
certainly do-able. It's very similar to dataToTag# in the way that the
argument is required to be evaluated - this is the main fragility,
unfortunately GHC doesn't have a way to talk about things that are
unlifted (except for the primitive unlifted types). But it just about
works if you make sure there's a seq in the right place.
Cheers,
Simon
More information about the Glasgow-haskell-users
mailing list