[commit: vector] simd: Incorporate prefetching. (7f1a61a)
Geoffrey Mainland
gmainlan at ghc.haskell.org
Fri Jul 19 14:24:58 CEST 2013
Repository : http://darcs.haskell.org/ghc.git/
On branch : simd
http://hackage.haskell.org/trac/ghc/changeset/7f1a61a8f546a3a837f74f92d71dced0c1ed94cf
>---------------------------------------------------------------
commit 7f1a61a8f546a3a837f74f92d71dced0c1ed94cf
Author: Geoffrey Mainland <mainland at apeiron.net>
Date: Thu Nov 15 14:56:29 2012 +0000
Incorporate prefetching.
>---------------------------------------------------------------
Data/Vector/Fusion/Bundle/Monadic.hs | 17 ++++++++++++-----
Data/Vector/Generic/Base.hs | 2 ++
Data/Vector/Storable.hs | 4 ++++
Data/Vector/Unboxed/Base.hs | 12 +++++++++++-
4 files changed, 29 insertions(+), 6 deletions(-)
diff --git a/Data/Vector/Fusion/Bundle/Monadic.hs b/Data/Vector/Fusion/Bundle/Monadic.hs
index 8954d04..68fe22a 100644
--- a/Data/Vector/Fusion/Bundle/Monadic.hs
+++ b/Data/Vector/Fusion/Bundle/Monadic.hs
@@ -113,6 +113,7 @@ import qualified Data.List as List
import Data.Char ( ord )
import GHC.Base ( unsafeChr )
import Control.Monad ( liftM )
+import Foreign ( sizeOf )
import Prelude hiding ( length, null,
replicate, (++),
head, last, (!!),
@@ -144,6 +145,9 @@ data Bundle m v a = Bundle { sElems :: Stream m a
}
#if defined(__GLASGOW_HASKELL_LLVM__)
+mAGIC_PREFETCH_CONSTANT :: Int
+mAGIC_PREFETCH_CONSTANT = 128*12
+
type Multis m a = Either (MultiStream m a) (Stream m (Either a (Multi a)))
toMixedStream :: Monad m => Multis m a -> Stream m (Either a (Multi a))
@@ -1322,9 +1326,11 @@ mzipWithHackM p q v1 v2 =
{-# INLINE stepm #-}
stepm i | i >= k = return Done
- | otherwise = case basicUnsafeIndexAsMultiM v1 i of
- Box x -> case basicUnsafeIndexAsMultiM v2 i of
- Box y -> liftM (`Yield` (i+m)) (q x y)
+ | otherwise = case basicUnsafePrefetchDataM v1 i mAGIC_PREFETCH_CONSTANT of
+ { Box v1' -> case basicUnsafePrefetchDataM v2 i mAGIC_PREFETCH_CONSTANT of
+ { Box v2' -> case basicUnsafeIndexAsMultiM v1' i of
+ { Box x -> case basicUnsafeIndexAsMultiM v2' i of
+ { Box y -> liftM (`Yield` (i+m)) (q x y) }}}}
{-# INLINE vstep #-}
vstep i = do r <- step i
@@ -1465,8 +1471,9 @@ fromPackedVector v = v `seq` n `seq` Bundle (Stream step 0)
{-# INLINE stepm #-}
stepm i | i >= k = return Done
- | otherwise = case basicUnsafeIndexAsMultiM v i of
- Box x -> return $ Yield x (i+m)
+ | otherwise = case basicUnsafePrefetchDataM v i mAGIC_PREFETCH_CONSTANT of
+ { Box v' -> case basicUnsafeIndexAsMultiM v' i of
+ { Box x -> return $ Yield x (i+m) }}
{-# INLINE step1 #-}
step1 i | i >= n = return Done
diff --git a/Data/Vector/Generic/Base.hs b/Data/Vector/Generic/Base.hs
index 2a2f03b..e127955 100644
--- a/Data/Vector/Generic/Base.hs
+++ b/Data/Vector/Generic/Base.hs
@@ -150,4 +150,6 @@ class (MultiType a, Vector v a, M.PackedMVector (Mutable v) a) => PackedVector v
-- | Yield the element at the given position in a monad. No range checks are
-- performed. The index is given in @a@'s, but the result is a @Multi a at .
basicUnsafeIndexAsMultiM :: Monad m => v a -> Int -> m (Multi a)
+
+ basicUnsafePrefetchDataM :: Monad m => v a -> Int -> Int -> m (v a)
#endif /* defined(__GLASGOW_HASKELL_LLVM__) */
diff --git a/Data/Vector/Storable.hs b/Data/Vector/Storable.hs
index 6f6ec72..2f876ad 100644
--- a/Data/Vector/Storable.hs
+++ b/Data/Vector/Storable.hs
@@ -265,6 +265,10 @@ instance (Storable a, MultiPrim a, Storable (Multi a))
= return $! unsafeInlineIO
$ withForeignPtr fp $ \p ->
peekElemOffAsMulti p i
+ {-# INLINE basicUnsafePrefetchDataM #-}
+ basicUnsafePrefetchDataM (Vector n fp) j k
+ = case prefetchForeignPtrData fp (j * sizeOf (undefined::a)+k) of
+ fp' -> return $ Vector n fp'
#endif /* defined(__GLASGOW_HASKELL_LLVM__) */
-- See http://trac.haskell.org/vector/ticket/12
diff --git a/Data/Vector/Unboxed/Base.hs b/Data/Vector/Unboxed/Base.hs
index baaadfc..bf3e5f7 100644
--- a/Data/Vector/Unboxed/Base.hs
+++ b/Data/Vector/Unboxed/Base.hs
@@ -34,6 +34,7 @@ import Control.Monad ( liftM )
#if defined(__GLASGOW_HASKELL_LLVM__)
import Data.Primitive.Multi
+import Foreign ( sizeOf )
#endif /* defined(__GLASGOW_HASKELL_LLVM__) */
import Data.Word ( Word, Word8, Word16, Word32, Word64 )
@@ -219,7 +220,11 @@ instance M.PackedMVector MVector ty where { \
instance G.PackedVector Vector ty where { \
{-# INLINE basicUnsafeIndexAsMultiM #-} \
; basicUnsafeIndexAsMultiM (con (P.Vector i _ arr)) j = \
- return $! indexByteArrayAsMulti arr (i+j) }
+ return $! indexByteArrayAsMulti arr (i+j) \
+; {-# INLINE basicUnsafePrefetchDataM #-} \
+; basicUnsafePrefetchDataM (con (P.Vector i n arr)) j k = \
+ do { arr' <- return $! prefetchByteArrayData arr ((i+j)*sizeOf (undefined::ty)+k) \
+ ; return (con (P.Vector i n arr')) }}
newtype instance MVector s Int = MV_Int (P.MVector s Int)
newtype instance Vector Int = V_Int (P.Vector Int)
@@ -461,4 +466,9 @@ instance (Unbox a, G.PackedVector Vector a) => G.PackedVector Vector (a, a) wher
do x <- G.basicUnsafeIndexAsMultiM v1 j
y <- G.basicUnsafeIndexAsMultiM v2 j
return $! M_2 x y
+
+ basicUnsafePrefetchDataM (V_2 n v1 v2) j k =
+ do v1' <- G.basicUnsafePrefetchDataM v1 j k
+ v2' <- G.basicUnsafePrefetchDataM v2 j k
+ return $! V_2 n v1' v2'
#endif /* defined(__GLASGOW_HASKELL_LLVM__) */
More information about the ghc-commits
mailing list