Skip to content

IOSim Timeouts API refactor and optimisation #3682

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from

Conversation

bolt12
Copy link
Contributor

@bolt12 bolt12 commented Mar 31, 2022

This PR implements and optimization to the timeout API, due to observable bottleneck on large Diffusion tests simulations.

NOTE: This PR is missing the IOSimPOR counterpart.

Benchmarks

Current master branch results

benchmarking delays/registerDelay
time                 3.290 ns   (3.282 ns .. 3.302 ns)
1.000 R²   (0.999 R² .. 1.000 R²)
mean                 3.355 ns   (3.309 ns .. 3.599 ns)
std dev              307.8 ps   (92.31 ps .. 734.7 ps)
variance introduced by outliers: 92% (severely inflated)

/nix/store/jdk8g1myxh379r9s88n1cvfwcs7pw5c6-cabal-install-exe-cabal-3.6.2.0/bin/cabal --project-file=/home/bolt/Desktop/Bolt/UMinho/Profissional/Well-Typed/Projects/IOHK/ouroboros-network/.nix-shell-cabal.project run io-sim:bench -- -o benchmarks/bench..threadDelay.html -L10 --match pattern delays/threadDelay
Up to date
benchmarking delays/threadDelay
time                 3.508 ns   (3.462 ns .. 3.578 ns)
0.997 R²   (0.995 R² .. 0.998 R²)
mean                 3.695 ns   (3.636 ns .. 3.759 ns)
std dev              245.1 ps   (220.8 ps .. 290.7 ps)
variance introduced by outliers: 85% (severely inflated)

/nix/store/jdk8g1myxh379r9s88n1cvfwcs7pw5c6-cabal-install-exe-cabal-3.6.2.0/bin/cabal --project-file=/home/bolt/Desktop/Bolt/UMinho/Profissional/Well-Typed/Projects/IOHK/ouroboros-network/.nix-shell-cabal.project run io-sim:bench -- -o benchmarks/bench..timeout-fail.html -L10 --match pattern delays/timeout/fail
Up to date
benchmarking delays/timeout/fail
time                 3.604 ns   (3.488 ns .. 3.733 ns)
0.993 R²   (0.990 R² .. 0.997 R²)
mean                 3.484 ns   (3.447 ns .. 3.563 ns)
std dev              197.6 ps   (132.6 ps .. 288.7 ps)
variance introduced by outliers: 81% (severely inflated)

/nix/store/jdk8g1myxh379r9s88n1cvfwcs7pw5c6-cabal-install-exe-cabal-3.6.2.0/bin/cabal --project-file=/home/bolt/Desktop/Bolt/UMinho/Profissional/Well-Typed/Projects/IOHK/ouroboros-network/.nix-shell-cabal.project run io-sim:bench -- -o benchmarks/bench..timeout-success.html -L10 --match pattern delays/timeout/succeed
Up to date
benchmarking delays/timeout/succeed
time                 4.104 ns   (4.021 ns .. 4.205 ns)
0.997 R²   (0.995 R² .. 0.999 R²)
mean                 4.123 ns   (4.076 ns .. 4.188 ns)
std dev              205.0 ps   (149.9 ps .. 307.3 ps)
variance introduced by outliers: 76% (severely inflated)

/nix/store/jdk8g1myxh379r9s88n1cvfwcs7pw5c6-cabal-install-exe-cabal-3.6.2.0/bin/cabal --project-file=/home/bolt/Desktop/Bolt/UMinho/Profissional/Well-Typed/Projects/IOHK/ouroboros-network/.nix-shell-cabal.project run io-sim:bench -- -o benchmarks/bench..timeout-racee.html -L10 --match pattern delays/timeout/race
Up to date
benchmarking delays/timeout/race
time                 3.972 ns   (3.953 ns .. 3.996 ns)
1.000 R²   (0.999 R² .. 1.000 R²)
mean                 3.985 ns   (3.970 ns .. 4.016 ns)
std dev              76.89 ps   (51.43 ps .. 122.4 ps)
variance introduced by outliers: 31% (moderately inflated)

/nix/store/jdk8g1myxh379r9s88n1cvfwcs7pw5c6-cabal-install-exe-cabal-3.6.2.0/bin/cabal --project-file=/home/bolt/Desktop/Bolt/UMinho/Profissional/Well-Typed/Projects/IOHK/ouroboros-network/.nix-shell-cabal.project run io-sim:bench -- -o benchmarks/bench..ping-ping.html -L10 --match pattern ping-pong/stm channel without delay
Up to date
benchmarking ping-pong/stm channel without delay
time                 3.124 ns   (3.104 ns .. 3.146 ns)
1.000 R²   (1.000 R² .. 1.000 R²)
mean                 3.110 ns   (3.099 ns .. 3.123 ns)
std dev              45.22 ps   (39.31 ps .. 55.24 ps)
variance introduced by outliers: 21% (moderately inflated)

/nix/store/jdk8g1myxh379r9s88n1cvfwcs7pw5c6-cabal-install-exe-cabal-3.6.2.0/bin/cabal --project-file=/home/bolt/Desktop/Bolt/UMinho/Profissional/Well-Typed/Projects/IOHK/ouroboros-network/.nix-shell-cabal.project run io-sim:bench -- -o benchmarks/bench..ping-ping.events.html -L10 --match pattern ping-pong/events
Up to date
benchmarking ping-pong/events
time                 6.956 ms   (6.891 ms .. 7.021 ms)
0.999 R²   (0.999 R² .. 1.000 R²)
mean                 7.196 ms   (7.123 ms .. 7.285 ms)
std dev              273.6 μs   (207.7 μs .. 359.8 μs)
variance introduced by outliers: 20% (moderately inflated)

/nix/store/jdk8g1myxh379r9s88n1cvfwcs7pw5c6-cabal-install-exe-cabal-3.6.2.0/bin/cabal --project-file=/home/bolt/Desktop/Bolt/UMinho/Profissional/Well-Typed/Projects/IOHK/ouroboros-network/.nix-shell-cabal.project run io-sim:bench -- -o benchmarks/bench..forkIO.silent.html -L10 --match pattern threads/50/forkIO silent
Up to date
benchmarking threads/50/forkIO silent
time                 2.892 ns   (2.727 ns .. 2.995 ns)
0.990 R²   (0.989 R² .. 0.993 R²)
mean                 2.656 ns   (2.611 ns .. 2.719 ns)
std dev              197.0 ps   (141.7 ps .. 250.2 ps)
variance introduced by outliers: 88% (severely inflated)

/nix/store/jdk8g1myxh379r9s88n1cvfwcs7pw5c6-cabal-install-exe-cabal-3.6.2.0/bin/cabal --project-file=/home/bolt/Desktop/Bolt/UMinho/Profissional/Well-Typed/Projects/IOHK/ouroboros-network/.nix-shell-cabal.project run io-sim:bench -- -o benchmarks/bench..forkIO.say.html -L10 --match pattern threads/50/forkIO say
Up to date
benchmarking threads/50/forkIO say
time                 6.383 ns   (6.329 ns .. 6.438 ns)
1.000 R²   (0.999 R² .. 1.000 R²)
mean                 6.382 ns   (6.352 ns .. 6.419 ns)
std dev              129.6 ps   (109.0 ps .. 162.4 ps)
variance introduced by outliers: 33% (moderately inflated)

/nix/store/jdk8g1myxh379r9s88n1cvfwcs7pw5c6-cabal-install-exe-cabal-3.6.2.0/bin/cabal --project-file=/home/bolt/Desktop/Bolt/UMinho/Profissional/Well-Typed/Projects/IOHK/ouroboros-network/.nix-shell-cabal.project run io-sim:bench -- -o benchmarks/bench..async.silent.html -L10 --match pattern threads/50/async silent
Up to date
benchmarking threads/50/async silent
time                 3.181 ns   (3.149 ns .. 3.220 ns)
0.999 R²   (0.999 R² .. 0.999 R²)
mean                 3.282 ns   (3.236 ns .. 3.347 ns)
std dev              205.1 ps   (164.4 ps .. 255.5 ps)
variance introduced by outliers: 83% (severely inflated)

/nix/store/jdk8g1myxh379r9s88n1cvfwcs7pw5c6-cabal-install-exe-cabal-3.6.2.0/bin/cabal --project-file=/home/bolt/Desktop/Bolt/UMinho/Profissional/Well-Typed/Projects/IOHK/ouroboros-network/.nix-shell-cabal.project run io-sim:bench -- -o benchmarks/bench..async.say.html -L10 --match pattern threads/50/async say
Up to date
benchmarking threads/50/async say
time                 189.0 ns   (187.1 ns .. 190.9 ns)
0.999 R²   (0.999 R² .. 1.000 R²)
mean                 188.0 ns   (187.2 ns .. 189.2 ns)
std dev              3.825 ns   (3.069 ns .. 5.443 ns)
variance introduced by outliers: 28% (moderately inflated)

/nix/store/jdk8g1myxh379r9s88n1cvfwcs7pw5c6-cabal-install-exe-cabal-3.6.2.0/bin/cabal --project-file=/home/bolt/Desktop/Bolt/UMinho/Profissional/Well-Typed/Projects/IOHK/ouroboros-network/.nix-shell-cabal.project run io-sim:bench -- -o benchmarks/bench..threadDelay.bottleneck.silent.html -L10 --match pattern threads/50/threadDelay bottleneck silent
Up to date
benchmarking threads/50/threadDelay bottleneck silent
time                 3.989 ns   (3.945 ns .. 4.061 ns)
0.999 R²   (0.998 R² .. 1.000 R²)
mean                 3.974 ns   (3.960 ns .. 3.995 ns)
std dev              67.36 ps   (49.74 ps .. 114.1 ps)
variance introduced by outliers: 26% (moderately inflated)

/nix/store/jdk8g1myxh379r9s88n1cvfwcs7pw5c6-cabal-install-exe-cabal-3.6.2.0/bin/cabal --project-file=/home/bolt/Desktop/Bolt/UMinho/Profissional/Well-Typed/Projects/IOHK/ouroboros-network/.nix-shell-cabal.project run io-sim:bench -- -o benchmarks/bench..threadDelay.bottleneck.say.html -L10 --match pattern threads/50/threadDelay bottleneck say
Up to date
benchmarking threads/50/threadDelay bottleneck say
time                 3.971 ms   (3.896 ms .. 4.050 ms)
0.999 R²   (0.998 R² .. 1.000 R²)
mean                 3.944 ms   (3.923 ms .. 3.976 ms)
std dev              93.60 μs   (73.64 μs .. 136.5 μs)
variance introduced by outliers: 11% (moderately inflated)

HEAD results

benchmarking delays/registerDelay
time                 3.291 ns   (3.281 ns .. 3.304 ns)
1.000 R²   (1.000 R² .. 1.000 R²)
mean                 3.294 ns   (3.288 ns .. 3.306 ns)
std dev              33.26 ps   (21.16 ps .. 51.43 ps)
variance introduced by outliers: 11% (moderately inflated)

/nix/store/jdk8g1myxh379r9s88n1cvfwcs7pw5c6-cabal-install-exe-cabal-3.6.2.0/bin/cabal --project-file=/home/bolt/Desktop/Bolt/UMinho/Profissional/Well-Typed/Projects/IOHK/ouroboros-network/.nix-shell-cabal.project run io-sim:bench -- -o benchmarks/bench.bolt12/io-sim-timout-optimisations.threadDelay.html -L10 --match pattern delays/threadDelay
Up to date
benchmarking delays/threadDelay
time                 3.306 ns   (3.284 ns .. 3.334 ns)
1.000 R²   (0.999 R² .. 1.000 R²)
mean                 3.300 ns   (3.291 ns .. 3.320 ns)
std dev              53.55 ps   (29.09 ps .. 97.83 ps)
variance introduced by outliers: 25% (moderately inflated)

/nix/store/jdk8g1myxh379r9s88n1cvfwcs7pw5c6-cabal-install-exe-cabal-3.6.2.0/bin/cabal --project-file=/home/bolt/Desktop/Bolt/UMinho/Profissional/Well-Typed/Projects/IOHK/ouroboros-network/.nix-shell-cabal.project run io-sim:bench -- -o benchmarks/bench.bolt12/io-sim-timout-optimisations.timeout-fail.html -L10 --match pattern delays/timeout/fail
Up to date
benchmarking delays/timeout/fail
time                 3.290 ns   (3.273 ns .. 3.316 ns)
1.000 R²   (1.000 R² .. 1.000 R²)
mean                 3.278 ns   (3.272 ns .. 3.289 ns)
std dev              31.06 ps   (19.62 ps .. 53.00 ps)

/nix/store/jdk8g1myxh379r9s88n1cvfwcs7pw5c6-cabal-install-exe-cabal-3.6.2.0/bin/cabal --project-file=/home/bolt/Desktop/Bolt/UMinho/Profissional/Well-Typed/Projects/IOHK/ouroboros-network/.nix-shell-cabal.project run io-sim:bench -- -o benchmarks/bench.bolt12/io-sim-timout-optimisations.timeout-success.html -L10 --match pattern delays/timeout/succeed
Up to date
benchmarking delays/timeout/succeed
time                 3.287 ns   (3.280 ns .. 3.297 ns)
1.000 R²   (1.000 R² .. 1.000 R²)
mean                 3.292 ns   (3.283 ns .. 3.310 ns)
std dev              44.50 ps   (22.99 ps .. 84.04 ps)
variance introduced by outliers: 19% (moderately inflated)

/nix/store/jdk8g1myxh379r9s88n1cvfwcs7pw5c6-cabal-install-exe-cabal-3.6.2.0/bin/cabal --project-file=/home/bolt/Desktop/Bolt/UMinho/Profissional/Well-Typed/Projects/IOHK/ouroboros-network/.nix-shell-cabal.project run io-sim:bench -- -o benchmarks/bench.bolt12/io-sim-timout-optimisations.timeout-racee.html -L10 --match pattern delays/timeout/race
Up to date
benchmarking delays/timeout/race
time                 3.336 ns   (3.297 ns .. 3.367 ns)
1.000 R²   (0.999 R² .. 1.000 R²)
mean                 3.302 ns   (3.295 ns .. 3.315 ns)
std dev              35.25 ps   (21.12 ps .. 53.21 ps)
variance introduced by outliers: 12% (moderately inflated)

/nix/store/jdk8g1myxh379r9s88n1cvfwcs7pw5c6-cabal-install-exe-cabal-3.6.2.0/bin/cabal --project-file=/home/bolt/Desktop/Bolt/UMinho/Profissional/Well-Typed/Projects/IOHK/ouroboros-network/.nix-shell-cabal.project run io-sim:bench -- -o benchmarks/bench.bolt12/io-sim-timout-optimisations.ping-ping.html -L10 --match pattern ping-pong/stm channel without delay
Up to date
benchmarking ping-pong/stm channel without delay
time                 2.717 ns   (2.706 ns .. 2.731 ns)
1.000 R²   (1.000 R² .. 1.000 R²)
mean                 2.729 ns   (2.720 ns .. 2.744 ns)
std dev              44.23 ps   (34.46 ps .. 61.97 ps)
variance introduced by outliers: 25% (moderately inflated)

/nix/store/jdk8g1myxh379r9s88n1cvfwcs7pw5c6-cabal-install-exe-cabal-3.6.2.0/bin/cabal --project-file=/home/bolt/Desktop/Bolt/UMinho/Profissional/Well-Typed/Projects/IOHK/ouroboros-network/.nix-shell-cabal.project run io-sim:bench -- -o benchmarks/bench.bolt12/io-sim-timout-optimisations.ping-ping.events.html -L10 --match pattern ping-pong/events
Up to date
benchmarking ping-pong/events
time                 5.578 ms   (5.529 ms .. 5.628 ms)
0.999 R²   (0.999 R² .. 1.000 R²)
mean                 5.654 ms   (5.607 ms .. 5.735 ms)
std dev              200.9 μs   (139.0 μs .. 297.9 μs)
variance introduced by outliers: 20% (moderately inflated)

/nix/store/jdk8g1myxh379r9s88n1cvfwcs7pw5c6-cabal-install-exe-cabal-3.6.2.0/bin/cabal --project-file=/home/bolt/Desktop/Bolt/UMinho/Profissional/Well-Typed/Projects/IOHK/ouroboros-network/.nix-shell-cabal.project run io-sim:bench -- -o benchmarks/bench.bolt12/io-sim-timout-optimisations.forkIO.silent.html -L10 --match pattern threads/50/forkIO silent
Up to date
benchmarking threads/50/forkIO silent
time                 2.846 ns   (2.685 ns .. 2.963 ns)
0.990 R²   (0.989 R² .. 0.994 R²)
mean                 2.641 ns   (2.607 ns .. 2.702 ns)
std dev              175.5 ps   (119.6 ps .. 232.9 ps)
variance introduced by outliers: 85% (severely inflated)

/nix/store/jdk8g1myxh379r9s88n1cvfwcs7pw5c6-cabal-install-exe-cabal-3.6.2.0/bin/cabal --project-file=/home/bolt/Desktop/Bolt/UMinho/Profissional/Well-Typed/Projects/IOHK/ouroboros-network/.nix-shell-cabal.project run io-sim:bench -- -o benchmarks/bench.bolt12/io-sim-timout-optimisations.forkIO.say.html -L10 --match pattern threads/50/forkIO say
Up to date
benchmarking threads/50/forkIO say
time                 7.036 ns   (6.982 ns .. 7.097 ns)
1.000 R²   (1.000 R² .. 1.000 R²)
mean                 7.046 ns   (7.020 ns .. 7.072 ns)
std dev              102.2 ps   (92.57 ps .. 119.9 ps)
variance introduced by outliers: 20% (moderately inflated)

/nix/store/jdk8g1myxh379r9s88n1cvfwcs7pw5c6-cabal-install-exe-cabal-3.6.2.0/bin/cabal --project-file=/home/bolt/Desktop/Bolt/UMinho/Profissional/Well-Typed/Projects/IOHK/ouroboros-network/.nix-shell-cabal.project run io-sim:bench -- -o benchmarks/bench.bolt12/io-sim-timout-optimisations.async.silent.html -L10 --match pattern threads/50/async silent
Up to date
benchmarking threads/50/async silent
time                 3.146 ns   (3.123 ns .. 3.178 ns)
0.999 R²   (0.999 R² .. 1.000 R²)
mean                 3.214 ns   (3.188 ns .. 3.244 ns)
std dev              110.1 ps   (91.22 ps .. 133.9 ps)
variance introduced by outliers: 60% (severely inflated)

/nix/store/jdk8g1myxh379r9s88n1cvfwcs7pw5c6-cabal-install-exe-cabal-3.6.2.0/bin/cabal --project-file=/home/bolt/Desktop/Bolt/UMinho/Profissional/Well-Typed/Projects/IOHK/ouroboros-network/.nix-shell-cabal.project run io-sim:bench -- -o benchmarks/bench.bolt12/io-sim-timout-optimisations.async.say.html -L10 --match pattern threads/50/async say
Up to date
benchmarking threads/50/async say
time                 172.8 ns   (172.2 ns .. 173.4 ns)
1.000 R²   (1.000 R² .. 1.000 R²)
mean                 173.6 ns   (173.0 ns .. 174.2 ns)
std dev              2.357 ns   (2.138 ns .. 2.710 ns)
variance introduced by outliers: 15% (moderately inflated)

/nix/store/jdk8g1myxh379r9s88n1cvfwcs7pw5c6-cabal-install-exe-cabal-3.6.2.0/bin/cabal --project-file=/home/bolt/Desktop/Bolt/UMinho/Profissional/Well-Typed/Projects/IOHK/ouroboros-network/.nix-shell-cabal.project run io-sim:bench -- -o benchmarks/bench.bolt12/io-sim-timout-optimisations.threadDelay.bottleneck.silent.html -L10 --match pattern threads/50/threadDelay bottleneck silent
Up to date
benchmarking threads/50/threadDelay bottleneck silent
time                 3.962 ns   (3.946 ns .. 3.977 ns)
1.000 R²   (1.000 R² .. 1.000 R²)
mean                 3.972 ns   (3.960 ns .. 3.985 ns)
std dev              48.67 ps   (43.83 ps .. 54.72 ps)
variance introduced by outliers: 15% (moderately inflated)

/nix/store/jdk8g1myxh379r9s88n1cvfwcs7pw5c6-cabal-install-exe-cabal-3.6.2.0/bin/cabal --project-file=/home/bolt/Desktop/Bolt/UMinho/Profissional/Well-Typed/Projects/IOHK/ouroboros-network/.nix-shell-cabal.project run io-sim:bench -- -o benchmarks/bench.bolt12/io-sim-timout-optimisations.threadDelay.bottleneck.say.html -L10 --match pattern threads/50/threadDelay bottleneck say
Up to date
benchmarking threads/50/threadDelay bottleneck say
time                 3.859 ms   (3.714 ms .. 4.067 ms)
0.988 R²   (0.978 R² .. 0.998 R²)
mean                 3.732 ms   (3.695 ms .. 3.816 ms)
std dev              195.9 μs   (106.6 μs .. 330.8 μs)
variance introduced by outliers: 38% (moderately inflated)

@bolt12 bolt12 linked an issue Mar 31, 2022 that may be closed by this pull request
@bolt12 bolt12 force-pushed the bolt12/io-sim-timout-optimisations branch 2 times, most recently from 18f639c to aaa47cf Compare April 5, 2022 16:12
@bolt12 bolt12 requested review from dcoutts and removed request for nfrisby and EncodePanda April 5, 2022 16:14
@bolt12 bolt12 force-pushed the bolt12/io-sim-timout-optimisations branch 6 times, most recently from 14f6979 to 9f30150 Compare April 8, 2022 10:11
@@ -639,6 +640,13 @@ data SimResult a

type SimTrace a = Trace.Trace (SimResult a) SimEvent

traceEvents :: SimTrace a -> [(Time, ThreadId, Maybe ThreadLabel, SimEventType)]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to move traceEvents to this module?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, that's something I forgot I had done, I'll revert this!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment on lines 340 to 445
tvar <- execNewTVar nextVid
(Just $ "<<timeout-state " ++ show (unTimeoutId nextTmid) ++ ">>")
TimeoutPending
let expiry = d `addTime` time
t = Timeout tvar nextTmid
timers' = PSQ.insert nextTmid expiry (Timer tvar) timers
thread' = thread { threadControl = ThreadControl (k t) ctl }
trace <- schedule thread' simstate { timers = timers'
, nextVid = succ nextVid
, nextTmid = succ nextTmid }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Were bangs removed by a rebase or do we actually want to remove them?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment on lines 397 to 398
let timers' = PSQ.delete tmid timers
thread' = thread { threadControl = ThreadControl k ctl }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

strict let bindings

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment on lines 422 to 546
let timers' = PSQ.delete tmid timers
thread' = thread { threadControl = ThreadControl k ctl }
written <- execAtomically' (runSTM $ writeTVar tvar TimeoutCancelled)
(wakeup, wokeby) <- threadsUnblockedByWrites written
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

strictness

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@bolt12 bolt12 force-pushed the bolt12/io-sim-timout-optimisations branch 2 times, most recently from 240a7e7 to e32aeef Compare April 11, 2022 10:46
Copy link
Contributor

@dcoutts dcoutts left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've only got through the first patch so far, sorry.

The main thing to watch out for is making too many unrelated changes in the same patch. Especially changing strictness.

Comment on lines 56 to 58
-- | Associated data type for 'timeout' API
--
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't really say anything that the syntax doesn't already say. Try and phrase it in terms of what it is for. Also note that it's not used with timeout, it's used with the "fancy" timeout API. Perhaps better to name them explicitly, e.g.

-- | The type of the timeout handle, used with 'newTimeout', 'readTimeout', 'updateTimeout' and 'cancelTimeout'.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment on lines +124 to +125
data TimerCompletionInfo s =
Timer !(TVar s TimeoutState)
| TimerRegisterDelay !(TVar s Bool)
| TimerThreadDelay !ThreadId
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@@ -332,38 +335,80 @@ schedule !thread@Thread{
let !t = NegativeTimeout nextTmid
!expiry = d `addTime` time
!thread' = thread { threadControl = ThreadControl (k t) ctl }
trace <- schedule thread' simstate { nextTmid = succ nextTmid }
!trace <- schedule thread' simstate { nextTmid = succ nextTmid }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we want to bang the result here. It is supposed to yield the trace lazily. That's why we use the lazy ST monad here.

But even if we do want to change it, it should not be done in this commit, since this commit is about something else, and it's better to have one logical change per commit.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

{-# SCC "schedule.UpdateTimeout" #-} do
let !timers' = PSQ.delete tmid timers
!thread' = thread { threadControl = ThreadControl k ctl }
trace <- schedule thread' simstate { timers = timers' }
!trace <- schedule thread' simstate { timers = timers' }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same with all of these: I'm not convinced they should be strict, but even if it should, that should be in its own patch, with a commit that explains why.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

(!wakeup, wokeby) <- threadsUnblockedByWrites written
mapM_ (\(SomeTVar var) -> unblockAllThreadsFromTVar var) written
(wakeup, wokeby) <- threadsUnblockedByWrites written
!_ <- mapM_ (\(SomeTVar var) -> unblockAllThreadsFromTVar var) written
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this necessary? Again, if so, separate patch.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

let (unblocked,
simstate') = unblockThreads wakeup simstate
-- Check all fired threadDelays
let !wakeupThreadDelay = mapMaybe threadDelayThreadId fired
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this I''d just use a list comprehension, rather than a separate named function. e.g.

let wakeupThreadDelay = [ tid | TimerThreadDelay tid <- fired ]

Note also that because it's a list, there's no point banging it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment on lines 148 to 156
NewTimeout :: DiffTime -> (Timeout (IOSim s) -> SimA s b) -> SimA s b
NewRegisterDelay :: DiffTime -> (TVar s Bool -> SimA s b) -> SimA s b
NewThreadDelay :: DiffTime -> SimA s b -> SimA s b

UpdateTimeout :: Timeout (IOSim s) -> DiffTime -> SimA s b -> SimA s b
CancelTimeout :: Timeout (IOSim s) -> SimA s b -> SimA s b
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just as a grouping thing: I'd keep the NewTimeout, UpdateTimeout, CancelTimeout together in one group, since they're one API together.

The NewRegisterDelay and NewThreadDelay are each independent timer/timeout/delay features and APIs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment on lines 778 to 771
| EventThreadDelay TimeoutId Time
| EventRegisterDelayCreated TimeoutId TVarId Time
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But note that they don't have their own expiry/end events. They use the same EventTimerExpired event. Arguably they should use their own. At least, EventThreadDelay should use its own, and would not need any TimeoutId since it happens only in the context of a single thread. The EventRegisterDelayCreated does indeed still need the TimeoutId since it's based on an independent TVar rather than being tied to a single thread.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

@@ -125,7 +123,10 @@ data TimerCompletionInfo s =
Timer !(TVar s TimeoutState)
| TimerRegisterDelay !(TVar s Bool)
| TimerThreadDelay !ThreadId
| TimerTimeout !ThreadId !TimeoutId
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So my suggestion is to put the lock in here, as a STVar s Bool.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually prefer the solution I went for, I think it is simpler and avoids having to use STM for handling timeouts inside IOSim, do you think it's worth to change?

@bolt12 bolt12 force-pushed the bolt12/io-sim-timout-optimisations branch from e32aeef to cea2d8e Compare April 12, 2022 15:11
@bolt12 bolt12 requested review from coot and dcoutts April 13, 2022 14:44
@bolt12 bolt12 force-pushed the bolt12/io-sim-timout-optimisations branch from cea2d8e to 4b99a9b Compare April 19, 2022 11:24
@coot
Copy link
Contributor

coot commented Apr 22, 2022

A test failed on CI with:

(Time 0s,MockEnvEvent (TraceEnvSetTargets (PeerSelectionTargets {targetNumberOfRootPeers = 0, targetNumberOfKnownPeers = 0, targetNumberOfEstablishedPeers = 0, targetNumberOfActivePeers = 0})))
FAIL
        *** Failed! (after 1 test and 6 shrinks):
        Exception:
          TODO
          CallStack (from HasCallStack):
            error, called at src/Control/Monad/IOSimPOR/Internal.hs:459:7 in io-sim-0.2.0.0-B67bgd08Dt8KdbMK71eRvo:Control.Monad.IOSimPOR.Internal
        GovernorMockEnvironment {peerGraph = PeerGraph [], localRootPeers = fromGroups [], publicRootPeers = fromList [], targets = Script ((PeerSelectionTargets {targetNumberOfRootPeers = 0, targetNumberOfKnownPeers = 0, targetNumberOfEstablishedPeers = 0, targetNumberOfActivePeers = 0},NoDelay) :| []), pickKnownPeersForGossip = Script (PickFirst :| []), pickColdPeersToPromote = Script (PickFirst :| []), pickWarmPeersToPromote = Script (PickFirst :| []), pickHotPeersToDemote = Script (PickFirst :| []), pickWarmPeersToDemote = Script (PickFirst :| []), pickColdPeersToForget = Script (PickFirst :| [])}
        Schedule control: ControlDefault
        No thread delayed
        *** Exception running callback: 
        TODO
        CallStack (from HasCallStack):
          error, called at src/Control/Monad/IOSimPOR/Internal.hs:459:7 in io-sim-0.2.0.0-B67bgd08Dt8KdbMK71eRvo:Control.Monad.IOSimPOR.Internal
        Use --quickcheck-replay=676939 to reproduce.
        Use -p '/races.governor connection status/' to rerun this test only.

@bolt12
Copy link
Contributor Author

bolt12 commented Apr 22, 2022

that's from the IOSimPOR side, which this PR doesn't tackle. Should it?

@coot
Copy link
Contributor

coot commented Apr 22, 2022

Ach, you're right. I don't think we can merge it until the IOSimPOR part is done, but since we found another way around iosim performance in general this is not high priority right now.

@bolt12
Copy link
Contributor Author

bolt12 commented Jun 20, 2022

Closing this PR in favor of input-output-hk/io-sim#9

@bolt12 bolt12 closed this Jun 20, 2022
@bolt12 bolt12 mentioned this pull request Jun 20, 2022
9 tasks
iohk-bors bot added a commit that referenced this pull request Jun 29, 2022
3820: Fixed KeepAlive Convergence test r=bolt12 a=bolt12

# Description

This small PR just extracts a particular commit from #3682 since now the actual PR lives in input-output-hk/io-sim#9.



Co-authored-by: Armando Santos <[email protected]>
@bolt12 bolt12 deleted the bolt12/io-sim-timout-optimisations branch May 8, 2023 10:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement IOSim timeout primitives
3 participants