Skip to content

Commit d1bc0a7

Browse files
committed
tx-submission: micro benchmark for makeDecisions
1 parent 9b8ccd6 commit d1bc0a7

File tree

9 files changed

+114
-18
lines changed

9 files changed

+114
-18
lines changed

ouroboros-network/bench/Main.hs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,16 @@
22

33
module Main (main) where
44

5+
import Control.DeepSeq
6+
import Control.Exception (evaluate)
7+
import Debug.Trace (traceMarkerIO)
8+
import System.Random.SplitMix qualified as SM
59
import Test.Tasty.Bench
610

11+
import Ouroboros.Network.TxSubmission.Inbound.V2.Decision qualified as Tx
12+
import Test.Ouroboros.Network.TxSubmission.TxLogic qualified as TX
13+
(mkDecisionContext)
14+
715
import Test.Ouroboros.Network.PeerSelection.PeerMetric
816
(microbenchmark1GenerateInput, microbenchmark1ProcessInput)
917

@@ -19,5 +27,48 @@ main =
1927
, env (microbenchmark1GenerateInput False 100_000) $ \i ->
2028
bench "100k" $ nfAppIO microbenchmark1ProcessInput i
2129
]
30+
, bgroup "TxLogic"
31+
[ env (do let a = TX.mkDecisionContext (SM.mkSMGen 131) 10
32+
evaluate (rnf a)
33+
traceMarkerIO "evaluated decision context"
34+
return a
35+
)
36+
(\a ->
37+
bench "makeDecisions: 10"
38+
$ nf (uncurry Tx.makeDecisions) a
39+
)
40+
, env (do let a = TX.mkDecisionContext (SM.mkSMGen 131) 100
41+
evaluate (rnf a)
42+
traceMarkerIO "evaluated decision context"
43+
return a
44+
)
45+
(\a ->
46+
bench "makeDecisions: 100"
47+
$ nf (uncurry Tx.makeDecisions) a
48+
)
49+
, env (do let a = TX.mkDecisionContext (SM.mkSMGen 361) 1_000
50+
evaluate (rnf a)
51+
traceMarkerIO "evaluated decision context"
52+
return a
53+
)
54+
(\a ->
55+
bench "makeDecisions: 1000"
56+
$ nf (uncurry Tx.makeDecisions) a
57+
)
58+
{-
59+
, env (do
60+
smGen <- SM.initSMGen
61+
print smGen
62+
let a = TX.mkDecisionContext smGen 1000
63+
evaluate (rnf a)
64+
traceMarkerIO "evaluated decision context"
65+
return a
66+
)
67+
(\a ->
68+
bench "makeDecisions: random"
69+
$ nf (uncurry Tx.makeDecisions) a
70+
)
71+
-}
72+
]
2273
]
2374
]

ouroboros-network/ouroboros-network.cabal

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,7 @@ library testlib
345345
psqueues,
346346
random,
347347
serialise,
348+
splitmix,
348349
tasty,
349350
tasty-hunit,
350351
tasty-quickcheck,
@@ -506,7 +507,9 @@ benchmark sim-benchmarks
506507
main-is: Main.hs
507508
build-depends:
508509
base,
509-
ouroboros-network:testlib,
510+
deepseq,
511+
ouroboros-network:{ouroboros-network, testlib},
512+
splitmix,
510513
tasty-bench >=0.3.5,
511514

512515
-- We use `-fproc-alignemtn` option to avoid skewed results due to changes in cache-line

ouroboros-network/src/Ouroboros/Network/TxSubmission/Inbound/V2/Decision.hs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ makeDecisions policy st =
8484
orderByRejections :: Hashable peeraddr
8585
=> Int
8686
-> Map peeraddr (PeerTxState txid tx)
87-
-> [ (peeraddr, PeerTxState txid tx)]
87+
-> [(peeraddr, PeerTxState txid tx)]
8888
orderByRejections salt =
8989
List.sortOn (\(peeraddr, ps) -> (score ps, hashWithSalt salt peeraddr))
9090
. Map.toList
@@ -103,7 +103,7 @@ data St peeraddr txid tx =
103103
-- ^ acknowledged `txid` with multiplicities. It is used to update
104104
-- `referenceCounts`.
105105

106-
stInSubmissionToMempoolTxs :: Set txid
106+
stInSubmissionToMempoolTxs :: !(Set txid)
107107
-- ^ TXs on their way to the mempool. Used to prevent issueing new
108108
-- fetch requests for them.
109109
}
@@ -258,10 +258,12 @@ pickTxsToDownload policy@TxDecisionPolicy { txsSizeInflightPerPeer,
258258
stInflight
259259
-- remove `tx`s which were already downloaded by some
260260
-- other peer or are in-flight or unknown by this peer.
261-
`Map.withoutKeys`
262-
(Map.keysSet bufferedTxs <> requestedTxsInflight <> unknownTxs
263-
<> stInSubmissionToMempoolTxs)
264-
261+
`Map.withoutKeys` (
262+
Map.keysSet bufferedTxs
263+
<> requestedTxsInflight
264+
<> unknownTxs
265+
<> stInSubmissionToMempoolTxs
266+
)
265267
)
266268
requestedTxsInflightSize
267269
-- pick from `txid`'s which are available from that given

ouroboros-network/src/Ouroboros/Network/TxSubmission/Inbound/V2/Policy.hs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ module Ouroboros.Network.TxSubmission.Inbound.V2.Policy
88
, NumTxIdsToReq (..)
99
) where
1010

11+
import Control.DeepSeq
1112
import Control.Monad.Class.MonadTime.SI
1213
import Ouroboros.Network.Protocol.TxSubmission2.Type (NumTxIdsToReq (..))
1314
import Ouroboros.Network.SizeInBytes (SizeInBytes (..))
@@ -64,6 +65,9 @@ data TxDecisionPolicy = TxDecisionPolicy {
6465
}
6566
deriving Show
6667

68+
instance NFData TxDecisionPolicy where
69+
rnf TxDecisionPolicy{} = ()
70+
6771
defaultTxDecisionPolicy :: TxDecisionPolicy
6872
defaultTxDecisionPolicy =
6973
TxDecisionPolicy {

ouroboros-network/src/Ouroboros/Network/TxSubmission/Inbound/V2/State.hs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -186,14 +186,18 @@ splitAcknowledgedTxIds
186186
(txIdsToRequest, acknowledgedTxIds', unacknowledgedTxIds')
187187
where
188188
(acknowledgedTxIds', unacknowledgedTxIds')
189-
= StrictSeq.spanl (\txid -> (txid `Map.member` bufferedTxs
190-
|| txid `Set.member` unknownTxs
191-
|| txid `Map.member` downloadedTxs)
192-
&& txid `Set.notMember` requestedTxsInflight
189+
= StrictSeq.spanl (\txid ->
190+
txid `Set.notMember` requestedTxsInflight
191+
&& (
192+
txid `Map.member` downloadedTxs
193+
|| txid `Set.member` unknownTxs
194+
|| txid `Map.member` bufferedTxs
195+
)
193196
)
194197
unacknowledgedTxIds
195-
numOfUnacked = StrictSeq.length unacknowledgedTxIds
196-
numOfAcked = StrictSeq.length acknowledgedTxIds'
198+
199+
numOfUnacked = StrictSeq.length unacknowledgedTxIds
200+
numOfAcked = StrictSeq.length acknowledgedTxIds'
197201
unackedAndRequested = fromIntegral numOfUnacked + requestedTxIdsInflight
198202

199203
txIdsToRequest =

ouroboros-network/src/Ouroboros/Network/TxSubmission/Inbound/V2/Types.hs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
{-# LANGUAGE DeriveAnyClass #-}
12
{-# LANGUAGE DeriveGeneric #-}
23
{-# LANGUAGE DerivingStrategies #-}
34
{-# LANGUAGE ExistentialQuantification #-}
@@ -35,6 +36,7 @@ module Ouroboros.Network.TxSubmission.Inbound.V2.Types
3536
, TxSubmissionProtocolError (..)
3637
) where
3738

39+
import Control.DeepSeq
3840
import Control.Exception (Exception (..))
3941
import Control.Monad.Class.MonadTime.SI
4042
import Data.Map.Strict (Map)
@@ -132,7 +134,7 @@ data PeerTxState txid tx = PeerTxState {
132134
toMempoolTxs :: !(Map txid tx)
133135

134136
}
135-
deriving (Eq, Show, Generic)
137+
deriving (Eq, Show, Generic, NFData)
136138

137139
instance ( NoThunks txid
138140
, NoThunks tx
@@ -242,7 +244,7 @@ data SharedTxState peeraddr txid tx = SharedTxState {
242244
-- | Rng used to randomly order peers
243245
peerRng :: !StdGen
244246
}
245-
deriving (Eq, Show, Generic)
247+
deriving (Eq, Show, Generic, NFData)
246248

247249
instance ( NoThunks peeraddr
248250
, NoThunks tx
@@ -256,7 +258,7 @@ instance ( NoThunks peeraddr
256258
--
257259

258260
newtype TxsToMempool txid tx = TxsToMempool { listOfTxsToMempool :: [(txid, tx)] }
259-
deriving newtype (Eq, Show, Semigroup, Monoid)
261+
deriving newtype (Eq, Show, Semigroup, Monoid, NFData)
260262

261263

262264
-- | Decision made by the decision logic. Each peer will receive a 'Decision'.
@@ -290,6 +292,10 @@ data TxDecision txid tx = TxDecision {
290292
}
291293
deriving (Show, Eq)
292294

295+
instance (NFData txid, NFData tx) => NFData (TxDecision txid tx) where
296+
-- all fields except `txdTxsToMempool` when evaluated to WHNF evaluate to NF.
297+
rnf TxDecision {txdTxsToMempool} = rnf txdTxsToMempool
298+
293299
-- | A non-commutative semigroup instance.
294300
--
295301
-- /note:/ this instance must be consistent with `pickTxsToDownload` and how

ouroboros-network/testlib/Test/Ouroboros/Network/PeerSelection/PeerMetric.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,7 @@ microbenchmark1GenerateInput verbose' n = do
447447
es <- generate (vector n)
448448
let fixedScript = mkFixedScript (Script (NonEmpty.fromList es))
449449
when verbose' $
450-
mapM_ print (let FixedScript s = fixedScript in s)
450+
mapM_ print (getFixedScript fixedScript)
451451
return fixedScript
452452

453453
-- TODO:

ouroboros-network/testlib/Test/Ouroboros/Network/TxSubmission/TxLogic.hs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ module Test.Ouroboros.Network.TxSubmission.TxLogic
1919
, PeerAddr
2020
, sharedTxStateInvariant
2121
, InvariantStrength (..)
22+
-- * Utils
23+
, mkDecisionContext
2224
) where
2325

2426
import Prelude hiding (seq)
@@ -39,6 +41,7 @@ import Data.Set (Set)
3941
import Data.Set qualified as Set
4042
import Data.Typeable
4143
import System.Random (StdGen, mkStdGen)
44+
import System.Random.SplitMix (SMGen)
4245

4346
import NoThunks.Class
4447

@@ -55,6 +58,8 @@ import Test.Ouroboros.Network.TxSubmission.Types
5558

5659
import Test.QuickCheck
5760
import Test.QuickCheck.Function (apply)
61+
import Test.QuickCheck.Gen (Gen (..))
62+
import Test.QuickCheck.Random (QCGen (..))
5863
import Test.Tasty (TestTree, testGroup)
5964
import Test.Tasty.QuickCheck (testProperty)
6065
import Text.Pretty.Simple
@@ -1224,6 +1229,25 @@ instance (Arbitrary txid, Ord txid, Function txid, CoArbitrary txid)
12241229
]
12251230

12261231

1232+
-- | Construct decision context in a deterministic way. For micro benchmarks.
1233+
--
1234+
-- It is based on QuickCheck's `arbitrary` instance for `ArbDecisionContexts.
1235+
--
1236+
mkDecisionContext :: SMGen
1237+
-- ^ pseudo random generator
1238+
-> Int
1239+
-- ^ size
1240+
-> (TxDecisionPolicy, SharedTxState PeerAddr TxId (Tx TxId))
1241+
mkDecisionContext stdgen size =
1242+
case unGen gen (QCGen stdgen) size of
1243+
ArbDecisionContexts { arbDecisionPolicy = policy,
1244+
arbSharedState = sharedState
1245+
} -> (policy, sharedState)
1246+
where
1247+
gen :: Gen (ArbDecisionContexts TxId)
1248+
gen = arbitrary
1249+
1250+
12271251
prop_ArbDecisionContexts_generator
12281252
:: ArbDecisionContexts TxId
12291253
-> Property

ouroboros-network/testlib/Test/Ouroboros/Network/TxSubmission/Types.hs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{-# LANGUAGE BangPatterns #-}
22
{-# LANGUAGE BlockArguments #-}
3+
{-# LANGUAGE DeriveAnyClass #-}
34
{-# LANGUAGE DeriveGeneric #-}
45
{-# LANGUAGE FlexibleContexts #-}
56
{-# LANGUAGE FlexibleInstances #-}
@@ -31,6 +32,7 @@ import Prelude hiding (seq)
3132
import NoThunks.Class
3233

3334
import Control.Concurrent.Class.MonadSTM
35+
import Control.DeepSeq
3436
import Control.Exception (SomeException (..))
3537
import Control.Monad.Class.MonadAsync
3638
import Control.Monad.Class.MonadFork
@@ -72,7 +74,7 @@ data Tx txid = Tx {
7274
-- invalid tx's in this sense.
7375
getTxValid :: !Bool
7476
}
75-
deriving (Eq, Ord, Show, Generic)
77+
deriving (Eq, Ord, Show, Generic, NFData)
7678

7779
instance NoThunks txid => NoThunks (Tx txid)
7880
instance ShowProxy txid => ShowProxy (Tx txid) where

0 commit comments

Comments
 (0)