From d47f24d7450c1d1ce23772988f407cb24f5b7d4c Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Fri, 5 Apr 2024 22:50:06 +0200 Subject: [PATCH] Scheduler-test: reorganise test-setup in Stress-test-rig MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With the addition of a second tool `bench::ParameterRange`, the setup of the test-context for measurement became confusing, since the original scheme was mostly oriented towards the ''breaking point search.'' On close investigation, I discovered several redundancies, and moreover, it seems questionable to generate an ''adapted-schedule'' for the Parameter-Range measurement method, which aims at overloading the scheduler and watch the time to resolve such a load peak. The solution entertained here is to move most of the schedule-ctx setup into the base implementation, which is typically just inherited by the actual testcase setup. This allows to leave the decision whether to build an adapted schedule to the actual tool. So `bench::BreakingPoint` can always setup the adapted schedule with a specific stress-factor, while `bench::ParameterRange` by default does nothing in this respect, and thus the `ScheduleCtx` will provide a default schedule with the configured level-duration (and the default for this is lowered to 200µs here). In a similar vein, calculation of result data points from the raw measurement is moved over into the actual test setup, thereby gaining flexibility. --- tests/vault/gear/scheduler-stress-test.cpp | 9 +- tests/vault/gear/stress-test-rig.hpp | 33 ++-- tests/vault/gear/test-chain-load.hpp | 6 - wiki/thinkPad.ichthyo.mm | 192 ++++++++++++++++++++- 4 files changed, 200 insertions(+), 40 deletions(-) diff --git a/tests/vault/gear/scheduler-stress-test.cpp b/tests/vault/gear/scheduler-stress-test.cpp index 206d2759d..c0c1fa677 100644 --- a/tests/vault/gear/scheduler-stress-test.cpp +++ b/tests/vault/gear/scheduler-stress-test.cpp @@ -393,7 +393,6 @@ namespace test { { usec LOAD_BASE = 500us; uint CONCURRENCY = 4; - bool showRuns = true; using Param = size_t; using Table = bench::DataTable; @@ -406,10 +405,12 @@ namespace test { } void - collectResult(Table& data, double millis, bench::IncidenceStat const& stat) + collectResult(Table& data, Param param, double millis, bench::IncidenceStat const& stat) { - data.time = stat.coveredTime / 1000; - data.conc = stat.avgConcurrency; + data.newRow(); + data.param = param; + data.time = stat.coveredTime / 1000; + data.conc = stat.avgConcurrency; data.jobtime = stat.activeTime/stat.activationCnt; data.overhead = stat.timeAtConc(1) / stat.activationCnt; ////OOO not really clear if sensible } diff --git a/tests/vault/gear/stress-test-rig.hpp b/tests/vault/gear/stress-test-rig.hpp index 56eba3418..7587650fe 100644 --- a/tests/vault/gear/stress-test-rig.hpp +++ b/tests/vault/gear/stress-test-rig.hpp @@ -168,6 +168,7 @@ namespace test { using usec = std::chrono::microseconds; usec LOAD_BASE = 500us; + usec LEVEL_STEP = 200us; usec BASE_EXPENSE = 0us; bool SCHED_NOTIFY = true; bool SCHED_DEPENDS = false; @@ -206,6 +207,11 @@ namespace test { testSetup (TL& testLoad) { return testLoad.setupSchedule(scheduler) + .withLoadTimeBase(LOAD_BASE) + .withLevelDuration(LEVEL_STEP) + .withBaseExpense (BASE_EXPENSE) + .withSchedNotify (SCHED_NOTIFY) + .withSchedDepends(SCHED_DEPENDS) .withJobDeadline(100ms) .withUpfrontPlanning(); } @@ -257,11 +263,7 @@ namespace test { void configureTest (TestSetup& testSetup, double stressFac) { - testSetup.withLoadTimeBase(CONF::LOAD_BASE) - .withBaseExpense (CONF::BASE_EXPENSE) - .withSchedNotify (CONF::SCHED_NOTIFY) - .withSchedDepends(CONF::SCHED_DEPENDS) - .withInstrumentation(CONF::INSTRUMENTATION) // side-effect: clear existing statistics + testSetup.withInstrumentation(CONF::INSTRUMENTATION) // side-effect: clear existing statistics .withAdaptedSchedule(stressFac, CONF::CONCURRENCY, adjustmentFac); } @@ -468,21 +470,14 @@ namespace test { void - runTest (Table& data) + runTest (Param param, Table& data) { - Param param = data.param; - double stressFac = 1.0; TestLoad testLoad = CONF::testLoad(param).buildTopology(); TestSetup testSetup = CONF::testSetup (testLoad) - .withLoadTimeBase(CONF::LOAD_BASE) - .withBaseExpense (CONF::BASE_EXPENSE) - .withSchedNotify (CONF::SCHED_NOTIFY) - .withSchedDepends(CONF::SCHED_DEPENDS) - .withAdaptedSchedule(stressFac, CONF::CONCURRENCY) - .withInstrumentation(); + .withInstrumentation(); // Note: by default Schedule with CONF::LEVEL_STEP double millis = testSetup.launch_and_wait() / 1000; auto stat = testSetup.getInvocationStatistic(); - CONF::collectResult (data, millis, stat); + CONF::collectResult (data, param, millis, stat); } public: @@ -514,12 +509,8 @@ namespace test { if (minP > lower) points[cnt-1] = lower; Table results; - for (Param& point : points) - { - results.newRow(); - results.param = point; - runTest (results); - } + for (Param point : points) + runTest (point, results); return results; } }; diff --git a/tests/vault/gear/test-chain-load.hpp b/tests/vault/gear/test-chain-load.hpp index 7d93139a0..68a621cf3 100644 --- a/tests/vault/gear/test-chain-load.hpp +++ b/tests/vault/gear/test-chain-load.hpp @@ -1944,12 +1944,6 @@ namespace test { return move(*this); } - ScheduleCtx&& - withBaseExpense () - { - return move(*this); - } - /** * Establish a differentiated schedule per level, taking node weights into account * @param stressFac further proportional tightening of the schedule times diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 52656ee1e..028213f8b 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -112002,14 +112002,59 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + + + + + +
    +
  • + legt Parameter-Typ und Ergebnis-Spalten fest +
  • +
  • + konfiguriert für jeden Lauf erneut einen Graphen +
  • +
  • + ist auch für das Aufsammeln der Ergebnisse zuständig +
  • +
+ +
+ +
- - - - + + + - + + + + + + + + + + + + + + + + + + + + + +

+ ...und was dieser Kontroll-Parameter tatsächlich ist, wird allein durch das Setup festgelegt — denn dies erzeugt sowohl jedesmal eine neue Topologie +

+ +
+
+
@@ -114733,7 +114778,8 @@ std::cout << tmpl.render({"what", "World"}) << s - + + @@ -114756,15 +114802,143 @@ std::cout << tmpl.render({"what", "World"}) << s - + + + + + +
    +
  • + weil es gar keine Zeit wäre, sondern ein Prozentsatz oder Faktor +
  • +
  • + und wenn es eine Zeit wäre, weil es sich auf einer komplett anderen Skala bewegt +
  • +
  • + oder weil es einige dramatische Ausreißer gibt und kein Pattern erkennbar ist +
  • +
+ +
+
+ + + + + + + + +

+ Das ist hier definitiv der Fall! +

+

+ Ich habe weitere »Slots« im Diagramm „zu vergeben“ und ich habe noch eine Menge Statistik-Daten sowie die Laufzeit instgesamt, die ich bisher gar nicht auswerte +

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

+ dort ist das Vorgeben eines Stress-Faktors für jeden Einzel-Lauf die zentrale Steuergröße, hier dagegen gehe ich eigentlich von einer Überlastung aus, und damit sollte das vorgefertigte Schedule nur zu dicht sein, ansonsten ist es egal +

+ +
+
+ + + + +

+ ...kann mir im Moment aber keine Fall vorstellen, wo man tatsächlich ein Schedule vorgeben und abarbeiten lassen möchte (weil dann die Messung nur einen kritischen Pfad durch das Schedule ermittelt, nicht den Scheduler selbst ausleuchtet ... anderenfalls wäre man wieder bei der breaking-Point-Suche) +

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

+ man könnte aber hier auch noch selber eingreifen +

+ +
+
+
+ + + + + +

+ ⟹ für das Tool »ParameterRange« wird per default kein (adapted) Schedule erstellt +

+ +
+ + + + + + + +

+ ...was nun relevant wird für das Tool »ParameterRange« — der feste default-Wert im Chain-Load-Schedule-Ctx ist 1ms, und das erscheint für diesen Zweck als zu hoch, weil damit die Gefahr besteht, den Worker-Pool gar nicht in die Voll-Auslastung zu bekommen +

+ +
+
+
+ +
- + +