Efficient UArray dot-product?
Mike Gunter
m@ryangunter.com
Sun, 02 Jun 2002 14:46:00 -0700
Is it possible to write an dot-product function that GHC will compile
to efficient code without using unsafeAt? I've tried and can't. I'm
looking at generic IArray functions pragma-specialized to UArray Int
Double. With unsafeAt the -ddump-simpl output looks optimal to me
(aside from not unrolling or pipelining**):
loop i s | i > ubSI = s
| otherwise = let s' = s + (small `unsafeAt` i) * (big `unsafeAt` (off + i))
in seq s' $ loop (i + 1) s'
compiles to
$wloop
= \ ww12 L :: PrelGHC.Int# ww13 L :: PrelGHC.Double# ->
case PrelGHC.># ww12 ww9 of wild3 L {
PrelBase.True -> PrelFloat.$wD# ww13;
PrelBase.False ->
$wloop
(PrelGHC.+# ww12 1)
(PrelGHC.+##
ww13
(PrelGHC.*##
(PrelGHC.indexDoubleArray# ww2 ww12)
(PrelGHC.indexDoubleArray# ww6 (PrelGHC.+# a2 ww12))))
};
} in
Without it (i.e. with (!)) the compiler will only use primitive
arithmetic for addressing one of the arrays. Why?
Is there a way to write dot-product that produces good code without
resorting to unsafeAt?
thanks,
mike
** Pipelining probably isn't going to be worth your time in so far as
you're targeting processors with dynamic scheduling. They'll
pipeline things for you.