From 3eaf623e9827f837ecb1c23c67dff4a5c0e3b03a Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Mon, 23 Oct 2023 23:55:54 +0200 Subject: [PATCH] Scheduler: develop scheme for capacity redirection ...to make that abundantly clear: we do not aim at precision timing, rather the goal is to redistribute capacity currently not usable... Basically we're telling the worker "nothing to do right now, sorry, but check back in because I may need you then" --- src/vault/gear/load-controller.hpp | 29 +++- .../gear/scheduler-load-control-test.cpp | 33 +++- wiki/thinkPad.ichthyo.mm | 144 +++++++++++++++++- 3 files changed, 196 insertions(+), 10 deletions(-) diff --git a/src/vault/gear/load-controller.hpp b/src/vault/gear/load-controller.hpp index 3e297edbc..af646b8bc 100644 --- a/src/vault/gear/load-controller.hpp +++ b/src/vault/gear/load-controller.hpp @@ -143,7 +143,7 @@ namespace gear { { } private: - Wiring wiring_; + const Wiring wiring_; TimeVar tendedHead_{Time::ANYTIME}; public: @@ -209,10 +209,31 @@ namespace gear { } - Time - scatteredDelayTime (Capacity capacity) + Offset + scatteredDelayTime (Time now, Capacity capacity) { - UNIMPLEMENTED ("establish a randomised targeted delay time"); + auto scatter = [&](Duration horizon) + { + size_t step = 1;////////////////////////////////////////////////////TODO implement randomisation + return Offset{_raw(horizon) * step / wiring_.maxCapacity}; + }; + + switch (capacity) { + case DISPATCH: + return Offset::ZERO; + case SPINTIME: + return Offset::ZERO; + case TENDNEXT: + return Offset{tendedHead_-now}; + case NEARTIME: + return Offset{tendedHead_-now + scatter(WORK_HORIZON)}; + case WORKTIME: + return Offset{tendedHead_-now + scatter(SLEEP_HORIZON)}; + case IDLETIME: + return /*without start offset*/ scatter(SLEEP_HORIZON); + default: + NOTREACHED ("uncovered work capacity classification."); + } } }; diff --git a/tests/vault/gear/scheduler-load-control-test.cpp b/tests/vault/gear/scheduler-load-control-test.cpp index 826d128c6..f56bf86ce 100644 --- a/tests/vault/gear/scheduler-load-control-test.cpp +++ b/tests/vault/gear/scheduler-load-control-test.cpp @@ -27,6 +27,7 @@ #include "lib/test/run.hpp" #include "vault/gear/load-controller.hpp" +#include "vault/real-clock.hpp" //#include "lib/time/timevalue.hpp" //#include "lib/format-cout.hpp" //#include "lib/util.hpp" @@ -34,7 +35,7 @@ //#include using test::Test; -//using std::move; +using std::move; //using util::isSameObject; @@ -46,6 +47,7 @@ namespace test { // using lib::time::Offset; // using lib::time::Time; using Capacity = LoadController::Capacity; + using Wiring = LoadController::Wiring; @@ -67,6 +69,7 @@ namespace test { classifyHorizon(); tendNextActivity(); classifyCapacity(); + scatteredReCheck(); walkingDeadline(); setupLalup(); } @@ -228,6 +231,34 @@ namespace test { } + + /** @test verify the re-distribution of free capacity by targeted delay + * @todo WIP 10/23 🔁 define ⟶ implement + */ + void + scatteredReCheck() + { + Wiring setup; + setup.maxCapacity = 16; + LoadController lctrl{move(setup)}; + + auto isBetween = [](auto lo, auto hi, auto val) + { + return lo <= val and val < hi; + }; + + TimeVar now = RealClock::now(); + Time next{now + FSecs(10)}; + lctrl.tendNext (next); + CHECK (Time::ZERO == lctrl.scatteredDelayTime (now, Capacity::DISPATCH) ); + CHECK (Time::ZERO == lctrl.scatteredDelayTime (now, Capacity::SPINTIME) ); + CHECK ( next == lctrl.scatteredDelayTime (now, Capacity::TENDNEXT) ); + CHECK (isBetween ( next, next+WORK_HORIZON , lctrl.scatteredDelayTime (now, Capacity::NEARTIME))); + CHECK (isBetween ( next, next+SLEEP_HORIZON, lctrl.scatteredDelayTime (now, Capacity::WORKTIME))); + CHECK (isBetween (Time::ZERO, SLEEP_HORIZON , lctrl.scatteredDelayTime (now, Capacity::IDLETIME))); + } + + /** @test TODO * @todo WIP 10/23 🔁 define ⟶ implement */ diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index f1b8e3b3c..1feda0621 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -82300,8 +82300,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
Parametrisierung: maxCapacity = work::Config::COMPUTATION_CAPACITY

- - + @@ -82728,6 +82727,119 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ Die Zeitangaben im std::chrono-Framework reichen bis in den Nano-Bereich, und es gibt einen high-precision-Timer +

+ + +
+
+ + + + + + +

+ ...andererseits weiß ich, daß man schon einfachste Scheduling-Delays ab mindestens 400ns mißt, und daß das Starten eines Thread auf meinem System mindestens 100µs braucht. Der aktuelle Scheduler unter Linux (CFS) verwendet keine festen Time-Slices mehr, aber man versucht definitiv die Kontext-Switches zu minimieren. Latenzen oder Scheduling-Zyklen für normale (nicht-realtime)-Prozesse liegen im Bereich von Millisekunden. Andererseits arbeitet die C++-Chrono-Funktion sleep_for nachweislich im Schnitt bis in den zweistelligen µs-Bereich genau +

+ + +
+
+ + + +
+
+ + + + +
+ + + + + + + + + + + +

+ die Funktion liefert eine Duration +

+ + +
+ + + + + + + + + + +

+ ...und spart einen zusätzlichen clamp-Schritt und den Absolutwert (den das OS sowiso machen wird) +

+ + +
+ + +
+
+
+
+ + + + + + + + + + + + + + @@ -90370,6 +90482,9 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + @@ -90903,7 +91018,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -90930,6 +91045,25 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + + + + + + + + + + + + + + @@ -95388,7 +95522,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -95590,7 +95724,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- +