Skip to content

Instantly share code, notes, and snippets.

@qnikst
Created April 20, 2013 06:16
Show Gist options
  • Save qnikst/5424967 to your computer and use it in GitHub Desktop.
Save qnikst/5424967 to your computer and use it in GitHub Desktop.
not fully correct crc16 implementation
-- Vector:
icsum16 :: Word32 -> V.Vector Word16 -> Word32
icsum16 !i bv = V.foldl' (\a -> (+a).fromIntegral) i bv
{-# INLINE icsum16 #-}
icsum16 :: Word32 -> Vector Word16 -> Word32
icsum16 =
\ (eta :: Word32) (eta1 :: Vector Word16) ->
let { Vector ipv ipv1 ipv2 ~ _ <- eta1 } in
let { W32# ww ~ _ <- eta } in
letrec {
$s$wfoldlM'_loop :: Word# -> Int# -> Word#
$s$wfoldlM'_loop =
\ (sc :: Word#) (sc1 :: Int#) ->
case >=# sc1 ipv of _ {
False ->
let { (# ipv3, ipv5 #) ~ _
<- readWord16OffAddr# ipv1 sc1 realWorld#
} in
let { __DEFAULT ~ _ <- touch# ipv2 ipv3 } in
$s$wfoldlM'_loop (narrow32Word# (plusWord# ipv5 sc)) (+# sc1 1);
True -> sc
}; } in
let { __DEFAULT ~ ww1 <- $s$wfoldlM'_loop ww 0 } in W32# ww1
benchmarking csumNew
mean: 381.5357 ns, lb 379.4919 ns, ub 384.6853 ns, ci 0.950
std dev: 12.81831 ns, lb 9.142332 ns, ub 16.99766 ns, ci 0.950
found 12 outliers among 100 samples (12.0%)
11 (11.0%) high severe
variance introduced by outliers: 29.670%
variance is moderately inflated by outliers
-- First approach to primops
--icsum16p :: Word32 -> V.Vector Word16 -> Word32
icsum16p !i bv = runST $ do
let crc a x = do
let !(W16# w#) = x
return $ a + W32# w#
V.foldM' crc i bv
$wicsum16p
:: Word# -> Int# -> Addr# -> ForeignPtrContents -> Word32
$wicsum16p =
\ (ww :: Word#)
(ww1 :: Int#)
(ww2 :: Addr#)
(ww3 :: ForeignPtrContents) ->
runSTRep
(\ (@ s) (w :: State# s) ->
letrec {
$s$wa1 :: Word# -> Int# -> State# s -> (# State# s, Word32 #)
$s$wa1 =
\ (sc :: Word#) (sc1 :: Int#) (sc2 :: State# s) ->
case >=# sc1 ww1 of _ {
False ->
let { (# ipv, ipv1 #) ~ _
<- readWord16OffAddr# ww2 sc1 realWorld#
} in
let { __DEFAULT ~ _ <- touch# ww3 ipv } in
$s$wa1 (narrow32Word# (plusWord# sc ipv1)) (+# sc1 1) sc2;
True -> (# sc2, W32# sc #)
}; } in
$s$wa1 ww 0 w)
icsum16p :: Word32 -> Vector Word16 -> Word32
icsum16p =
\ (w :: Word32) (w1 :: Vector Word16) ->
let { W32# ww ~ _ <- w } in
let { Vector ww1 ww2 ww3 ~ _ <- w1 } in $wicsum16p ww ww1 ww2 ww3
benchmarking csumNew1
mean: 387.5422 ns, lb 385.8914 ns, ub 390.4234 ns, ci 0.950
std dev: 10.89284 ns, lb 7.120208 ns, ub 16.06513 ns, ci 0.950
found 13 outliers among 100 samples (13.0%)
2 (2.0%) high mild
11 (11.0%) high severe
variance introduced by outliers: 22.861%
variance is moderately inflated by outliers
-- PrimOps by hands
icsum16p2 :: Word32 -> Addr# -> Int -> Word32
icsum16p2 !(W32# i#) a# !l = runST (go i# 0)
where
a = P.Addr a#
{-# INLINE a #-}
-- go :: Word# -> Int -> m Word32
go w# x | x >= l = return (W32# w#)
| otherwise = do
v <- a `P.readOffAddr` x
let !(W16# v#) = v
go (narrow32Word# (w# `plusWord#` v#)) (x+1)
{-# INLINE go #-}
{-# INLINE icsum16p2 #-}
icsum16p2 :: Word32 -> Addr# -> Int -> Word32
icsum16p2 =
\ (eta :: Word32) (eta1 :: Addr#) (eta2 :: Int) ->
let { W32# i# ~ _ <- eta } in
let { I# ipv ~ _ <- eta2 } in
runSTRep
(\ (@ s) (w :: State# s) ->
letrec {
$wa4 :: Word# -> Int# -> State# s -> (# State# s, Word32 #)
$wa4 =
\ (w1 :: Word#) (ww :: Int#) (w2 :: State# s) ->
case >=# ww ipv of _ {
False ->
let { (# ipv1, ipv2 #) ~ _
<- readWord16OffAddr# eta1 ww (w2 `cast` ...)
} in
$wa4
(narrow32Word# (plusWord# w1 ipv2)) (+# ww 1) (ipv1 `cast` ...);
True -> (# w2, W32# w1 #)
}; } in
$wa4 i# 0 w)
benchmarking csumNew2
mean: 719.7642 ns, lb 716.4036 ns, ub 725.5346 ns, ci 0.950
std dev: 21.82769 ns, lb 14.58964 ns, ub 31.41340 ns, ci 0.950
found 8 outliers among 100 samples (8.0%)
8 (8.0%) high severe
variance introduced by outliers: 25.761%
variance is moderately inflated by outliers
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment