From 5abab5390d7eabc0753587fb855e1979bd352f3d Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Thu, 7 Dec 2023 21:02:39 +0100 Subject: [PATCH] Scheduler: start-up working -- no need for pre-delay Introducing a fixed pre-delay on each new Calc-Streem seemed like an obvious remedy, yet on closer investigation it turned out that the start-up logic as such was contradictory, which was only uncovered by some rather special schedule patterns. After fixing the logic deficiencies, Scheduler starts up as intended and the probabilistic capacity-control seems to work as designed. Thus no need to introduce an artificial delay at begin, even while this implies that typically the first round of job-planning will be performed synchronous, in the invoking thread (which may be surprising, but is completely within the limits of the architecture; we do not employ specifically configured threads and planning should be done in short chunks, thus the first chunk can well be done by the caller) --- src/vault/gear/scheduler.hpp | 3 +- wiki/thinkPad.ichthyo.mm | 264 ++++++++++++++++++++++++----------- 2 files changed, 185 insertions(+), 82 deletions(-) diff --git a/src/vault/gear/scheduler.hpp b/src/vault/gear/scheduler.hpp index 3fd71806d..11cb8628d 100644 --- a/src/vault/gear/scheduler.hpp +++ b/src/vault/gear/scheduler.hpp @@ -142,7 +142,6 @@ namespace gear { const auto IDLE_WAIT = 20ms; ///< sleep-recheck cycle for workers deemed _idle_ const size_t DISMISS_CYCLES = 100; ///< number of wait cycles before an idle worker terminates completely Offset POLL_WAIT_DELAY{FSecs(1,1000)}; ///< delay until re-evaluating a condition previously found unsatisfied - Offset SEED_CALC_OFFSET{_uTicks(250us)}; ///< tiny delay to ensure the first job is actually enqueued to force ignite() Offset DUTY_CYCLE_PERIOD{FSecs(1,20)}; ///< period of the regular scheduler »tick« for state maintenance. Offset DUTY_CYCLE_TOLERANCE{FSecs(1,10)}; ///< maximum slip tolerated on duty-cycle start before triggering Scheduler-emergency } @@ -332,7 +331,7 @@ namespace gear { { layer1_.activate (manID); activityLang_.announceLoad (expectedAdditionalLoad); - continueMetaJob (RealClock::now()+SEED_CALC_OFFSET, planningJob, manID); + continueMetaJob (RealClock::now(), planningJob, manID); } diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index b51fba85d..1f7b8dd31 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -82752,10 +82752,10 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - - + + + + @@ -82797,9 +82797,24 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
-
- + + + + + + + + + + + + + + + + + @@ -85023,9 +85038,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

warum....? weiß nicht, Bauchgefühl. @@ -85034,8 +85047,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
Ich möchte nicht mit Einzelfall-Analysen belegen, wann der Scheduler gestartet werden soll. Der Ruhe-Zustand, wie auch der Neuanlauf sollten von außen praktisch nicht erkennbar sein (bis auf die Verzögerung)

- -
+
@@ -85069,7 +85081,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -85088,7 +85100,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -85118,12 +85130,12 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + - + @@ -85139,19 +85151,19 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - + + + + + - + - - - @@ -85163,6 +85175,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ @@ -95850,8 +95863,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -95914,7 +95927,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -95924,6 +95937,16 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + +

+ ...war nichts Grundsätzliches ... die Logik wollte nur zu viel mit zu geringen Mitteln; etwas auseinandergezogen und expliziter programmiert +

+ +
+
@@ -100883,9 +100906,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

Gut daß wir darüber geredet haben. @@ -100894,8 +100915,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
Da offensichtlich die Länge des Test-Graphen keine Eigenschaft  der Teststruktur ist, landen wir bei einer rein dynamischen Allokation. Trotzdem war es eine gute Idee, das mit der uninitialised storage  endlich mal zu codifizierren...

- -
+
@@ -101272,16 +101292,13 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

...und das ist gut so

- -
+
@@ -101357,7 +101374,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -101377,6 +101394,15 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + +
+ +
@@ -101390,16 +101416,13 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

Nebeneinsicht: darf nur ein wirklich leeres Signal kaputt schießen

- -
+
@@ -101410,16 +101433,13 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

Hilfsfunktion, die beim ersten Aufruf den Bezugspunkt setzt. Dafür sorgen, daß dieser erste Aufruf den Anker-Punkt anfragt. Hilfsfunktion gibt dann µs nach Anker aus

- -
+
@@ -101429,16 +101449,13 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

⟹ der pre-Roll ist wesentlich zu kurz

- -
+
@@ -101454,16 +101471,13 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

Graph als DOT anschauen, ist ja reproduzierbar und enthält die Node-IDs

- -
+
@@ -101485,9 +101499,56 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + + + + + + + + + + + + + + + + + +

+ das ist incoming capacity +

+ +
+ +
+ + + + + + +

+ dieser Fall ist in der Tat etwas „ausgefallen“: wenn die ersten planmäßigen Tasks jenseits des WORK_HORIZON liegen, muß man damit rechnen, daß die ganze Kapazität gebündelt einmal kurz hinter dem SLEEP_HORIZON auftaucht und „nachschaut“...  +

+

+ ...und solange keine Jobs im Nahfeld auftreten, kommt es auch erst mal nicht zu einer Umverteilung der Kapazität. Das ist eine Konsequenz der Entscheidung, das längerfristige Schlafen zu priorisieren. Letztlich ist auch der SLEEP_HORIZON so zu wählen, daß er noch nicht gefährlich lang ist im Verhältnis zum zu erwartenden Takt (den ich auf ca 25fps schätze) +

+ +
+ + +
+
+
+
+
+ + + @@ -101586,6 +101647,64 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + + + + + + + + + +

+ works as designed +

+
    +
  • + freut mich — das Monster ist zahm +
  • +
  • + Verhalten erscheint oft auf den ersten Blick sonderbar +
  • +
  • + man muß wirklich in diesen Zeit-Dimensionen denken +
  • +
  • + ob das wirklich brauchbar ist — muß sich erst noch zeigen +
  • +
+ +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + @@ -102669,16 +102788,13 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

Wie viel dedizierte Logik ist hierfür sinnvoll?

- -
+
@@ -108725,16 +108841,13 @@ class Something - - - +

es ist ein einmal-Kommunikationskanal

- -
+
@@ -108745,27 +108858,21 @@ class Something - - - +

Endpunkte werden normalerweise vorher erstellt

- -
+ - - - +

...will sagen, bevor die »concurrent operation« überhaupt beginnt; also beispielsweise bevor man einen Worker-Thread startet, ist zumindest der Promise (und damit der shared-state) schon erzeugt. Ein Future kann man dann später davon ableiten (is clearly sequenced). Wenn man Endpunkte über Thread-Grenzen hinweg weitereichen möchte, ist das nicht durch den Future-Promise-Mechanismus gedeckt und muß anderweitig konventionell synchronisiert werden.

- -
+
@@ -108781,16 +108888,13 @@ class Something - - - +

also ein shared_ptr != null

- -
+