You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
| bi .&. b ==0= step ary mary b i j (bi `unsafeShiftL`1) n
|otherwise=case go (A.index ary i) of
Empty-> step ary mary (b .&. complement bi) (i+1) j
(bi `unsafeShiftL`1) n
t ->doA.write mary j t
step ary mary b (i+1) (j+1) (bi `unsafeShiftL`1) n
filterC ary0 h =
let!n =A.length ary0
in runST $do
mary <-A.new_ n
step ary0 mary 00 n
where
step::A.Array (Leafkv1) ->A.MArrays (Leafkv2)
->Int->Int->Int
->STs (HashMapkv2)
step !ary !mary i !j n
| i >= n =case j of
0->returnEmpty
1->do l <-A.read mary 0
return$!Leaf h l
_ | i == j ->do ary2 <-A.unsafeFreeze mary
return$!Collision h ary2
|otherwise->do ary2 <-A.trim mary j
return$!Collision h ary2
|Just el <- onColl $!A.index ary i
=A.write mary j el >> step ary mary (i+1) (j+1) n
|otherwise= step ary mary (i+1) j n
{-# INLINE filterMapAux #-}
The inner step loops currently work by reading from input Arrays and writing to new_ output MArrays. If we were to give up the code sharing, the loops in filter[WithKey] could perform both reads and writes on thawed output MArrays, removing the input arrays arguments from the inner loops, and possibly increasing cache locality.
For filterC, this might look roughly like this:
@@ -2116,13 +2116,13 @@ filterMapAux onLeaf onColl = go
filterC ary0 h =
let !n = A.length ary0
in runST $ do
- mary <- A.new_ n- step ary0 mary 0 0 n+ mary <- A.thaw ary0 0 n+ step mary 0 0 n
where
- step :: A.Array (Leaf k v1) -> A.MArray s (Leaf k v2)+ step :: A.MArray s (Leaf k v2)
-> Int -> Int -> Int
-> ST s (HashMap k v2)
- step !ary !mary i !j n+ step !mary i !j n
| i >= n = case j of
0 -> return Empty
1 -> do l <- A.read mary 0
@@ -2131,9 +2131,10 @@ filterMapAux onLeaf onColl = go
return $! Collision h ary2
| otherwise -> do ary2 <- A.unsafeFreeze =<< A.shrink mary j
return $! Collision h ary2
- | Just el <- onColl $! A.index ary i- = A.write mary j el >> step ary mary (i+1) (j+1) n- | otherwise = step ary mary (i+1) j n+ | otherwise = do+ case A.read mary i of+ Just el -> A.write mary j el >> step mary (i+1) (j+1) n+ Nothing -> step mary (i+1) j n
{-# INLINE filterMapAux #-}
The text was updated successfully, but these errors were encountered:
If one of the arrays falls out of L2 cache while applying the filter function, then the other one will probably do so too. I don't think cache locality is likely to be an issue there. That leaves register pressure, I guess? I don't know enough about such low-level stuff, TBH, but I guess it could make a difference.
These functions are currently sharing code with
mapMaybe[WithKey]
viafilterMapAux
.unordered-containers/Data/HashMap/Internal.hs
Lines 2070 to 2137 in 19674b5
The inner
step
loops currently work by reading from inputArray
s and writing tonew_
outputMArray
s. If we were to give up the code sharing, the loops infilter[WithKey]
could perform both reads and writes onthaw
ed outputMArray
s, removing the input arrays arguments from the inner loops, and possibly increasing cache locality.For
filterC
, this might look roughly like this:The text was updated successfully, but these errors were encountered: