From f4dd3094766a10045f4eb99b6ba2651a72a56571 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Mon, 1 Jan 2024 20:06:53 +0100 Subject: [PATCH] Scheduler-test: change test setup to use a schedule table ...up to now, we've relied on a regular schedule governed solely by the progression of node levels, with a fixed level speed defaulting to 1ms per level. But in preparation of stress tesging, we need a schedule adapted to the expected distribution of computation times, otherwise we'll not be able to factor out the actual computation graph connectivity. The goal is to establish a distinctive **breaking point** when the scheduler is unable to cope with the provided schedule. --- tests/vault/gear/scheduler-stress-test.cpp | 128 ++++----------------- tests/vault/gear/test-chain-load.hpp | 106 +++++++++++++---- wiki/thinkPad.ichthyo.mm | 84 +++++++++++--- 3 files changed, 170 insertions(+), 148 deletions(-) diff --git a/tests/vault/gear/scheduler-stress-test.cpp b/tests/vault/gear/scheduler-stress-test.cpp index 490cccaf3..d46eeecf1 100644 --- a/tests/vault/gear/scheduler-stress-test.cpp +++ b/tests/vault/gear/scheduler-stress-test.cpp @@ -163,114 +163,34 @@ SHOW_EXPR(micros); CHECK (micros < 550); CHECK (micros > 450); - auto node = testLoad.allNodePtr().effuse(); - auto level = testLoad.allLevelWeights().effuse(); - CHECK (level.size() == 27); - - _Fmt nodeFmt{"i=%-2d lev:%-2d w=%1d"}; - _Fmt levelFmt{" Σ%-2d Σw:%2d"}; - auto nodeStr = [&](uint i) - { - size_t l = node[i]->level; - return string{nodeFmt % i % node[i]->level % node[i]->weight} - + (i == level[l].endidx? string{levelFmt % level[l].nodes % level[l].weight} - : string{" · · "}); - }; - // |idx--level--wght|-levelSum------- - CHECK (nodeStr( 1) == "i=1 lev:1 w=0 Σ1 Σw: 0"_expect); - CHECK (nodeStr( 2) == "i=2 lev:2 w=2 Σ1 Σw: 2"_expect); - CHECK (nodeStr( 3) == "i=3 lev:3 w=0 Σ1 Σw: 0"_expect); - CHECK (nodeStr( 4) == "i=4 lev:4 w=0 Σ1 Σw: 0"_expect); - CHECK (nodeStr( 5) == "i=5 lev:5 w=0 Σ1 Σw: 0"_expect); - CHECK (nodeStr( 6) == "i=6 lev:6 w=1 Σ1 Σw: 1"_expect); - CHECK (nodeStr( 7) == "i=7 lev:7 w=2 Σ1 Σw: 2"_expect); - CHECK (nodeStr( 8) == "i=8 lev:8 w=2 Σ1 Σw: 2"_expect); - CHECK (nodeStr( 9) == "i=9 lev:9 w=1 · · "_expect); - CHECK (nodeStr(10) == "i=10 lev:9 w=1 Σ2 Σw: 2"_expect); - CHECK (nodeStr(11) == "i=11 lev:10 w=0 · · "_expect); - CHECK (nodeStr(12) == "i=12 lev:10 w=0 Σ2 Σw: 0"_expect); - CHECK (nodeStr(13) == "i=13 lev:11 w=0 · · "_expect); - CHECK (nodeStr(14) == "i=14 lev:11 w=0 Σ2 Σw: 0"_expect); - CHECK (nodeStr(15) == "i=15 lev:12 w=1 · · "_expect); - CHECK (nodeStr(16) == "i=16 lev:12 w=1 Σ2 Σw: 2"_expect); - CHECK (nodeStr(17) == "i=17 lev:13 w=1 · · "_expect); - CHECK (nodeStr(18) == "i=18 lev:13 w=1 Σ2 Σw: 2"_expect); - CHECK (nodeStr(19) == "i=19 lev:14 w=2 · · "_expect); - CHECK (nodeStr(20) == "i=20 lev:14 w=2 Σ2 Σw: 4"_expect); - CHECK (nodeStr(21) == "i=21 lev:15 w=0 Σ1 Σw: 0"_expect); - CHECK (nodeStr(22) == "i=22 lev:16 w=1 Σ1 Σw: 1"_expect); - CHECK (nodeStr(23) == "i=23 lev:17 w=3 Σ1 Σw: 3"_expect); - CHECK (nodeStr(24) == "i=24 lev:18 w=0 · · "_expect); - CHECK (nodeStr(25) == "i=25 lev:18 w=0 · · "_expect); - CHECK (nodeStr(26) == "i=26 lev:18 w=0 · · "_expect); - CHECK (nodeStr(27) == "i=27 lev:18 w=0 · · "_expect); - CHECK (nodeStr(28) == "i=28 lev:18 w=0 Σ5 Σw: 0"_expect); - CHECK (nodeStr(29) == "i=29 lev:19 w=2 · · "_expect); - CHECK (nodeStr(30) == "i=30 lev:19 w=2 · · "_expect); - CHECK (nodeStr(31) == "i=31 lev:19 w=2 · · "_expect); - CHECK (nodeStr(32) == "i=32 lev:19 w=2 · · "_expect); - CHECK (nodeStr(33) == "i=33 lev:19 w=2 Σ5 Σw:10"_expect); - CHECK (nodeStr(34) == "i=34 lev:20 w=3 · · "_expect); - CHECK (nodeStr(35) == "i=35 lev:20 w=2 Σ2 Σw: 5"_expect); - CHECK (nodeStr(36) == "i=36 lev:21 w=1 · · "_expect); - CHECK (nodeStr(37) == "i=37 lev:21 w=1 · · "_expect); - CHECK (nodeStr(38) == "i=38 lev:21 w=3 Σ3 Σw: 5"_expect); - CHECK (nodeStr(39) == "i=39 lev:22 w=3 · · "_expect); - CHECK (nodeStr(40) == "i=40 lev:22 w=3 · · "_expect); - CHECK (nodeStr(41) == "i=41 lev:22 w=0 · · "_expect); - CHECK (nodeStr(42) == "i=42 lev:22 w=0 · · "_expect); - CHECK (nodeStr(43) == "i=43 lev:22 w=0 · · "_expect); - CHECK (nodeStr(44) == "i=44 lev:22 w=0 Σ6 Σw: 6"_expect); - CHECK (nodeStr(45) == "i=45 lev:23 w=0 · · "_expect); - - - CHECK (level[19].nodes = 5); - CHECK (level[19].weight = 10); - CHECK (computeWeightFactor(level[19], 1) == 10.0); - CHECK (computeWeightFactor(level[19], 2) == 10.0 / (5.0/3)); - CHECK (computeWeightFactor(level[19], 3) == 10.0 / (5.0/2)); - CHECK (computeWeightFactor(level[19], 4) == 10.0 / (5.0/2)); - CHECK (computeWeightFactor(level[19], 5) == 10.0 / (5.0/1)); - -SHOW_EXPR(level.size()) - + // build a schedule sequence based on + // summing up weight factors, with example concurrency ≔ 4 uint concurrency = 4; - auto steps = testLoad.levelScheduleSequence(concurrency).effuse(); - CHECK (steps.size() == 27); + auto stepsFactors = testLoad.levelScheduleSequence(concurrency).effuse(); + CHECK (stepsFactors.size() == 1+testLoad.topLevel()); + CHECK (stepsFactors.size() == 27); - auto boost = [&](uint i){ return level[i].nodes / std::ceil (double(level[i].nodes)/concurrency); }; - auto wfact = [&](uint i){ return computeWeightFactor(level[i], concurrency); }; - _Fmt stepFmt{"lev:%-2d nodes:%-2d Σw:%2d %4.1f Δ%5.3f ▿▿ %6.3f"}; - auto stepStr = [&](uint i){ return string{stepFmt % i % level[i].nodes % level[i].weight % boost(i) % wfact(i) % steps[i]}; }; + // Build-Performance-test-setup-------- + BlockFlowAlloc bFlow; + EngineObserver watch; + Scheduler scheduler{bFlow, watch}; - CHECK (stepStr( 0) == "lev:0 nodes:1 Σw: 0 1.0 Δ0.000 ▿▿ 0.000"_expect); - CHECK (stepStr( 1) == "lev:1 nodes:1 Σw: 0 1.0 Δ0.000 ▿▿ 0.000"_expect); - CHECK (stepStr( 2) == "lev:2 nodes:1 Σw: 2 1.0 Δ2.000 ▿▿ 2.000"_expect); - CHECK (stepStr( 3) == "lev:3 nodes:1 Σw: 0 1.0 Δ0.000 ▿▿ 2.000"_expect); - CHECK (stepStr( 4) == "lev:4 nodes:1 Σw: 0 1.0 Δ0.000 ▿▿ 2.000"_expect); - CHECK (stepStr( 5) == "lev:5 nodes:1 Σw: 0 1.0 Δ0.000 ▿▿ 2.000"_expect); - CHECK (stepStr( 6) == "lev:6 nodes:1 Σw: 1 1.0 Δ1.000 ▿▿ 3.000"_expect); - CHECK (stepStr( 7) == "lev:7 nodes:1 Σw: 2 1.0 Δ2.000 ▿▿ 5.000"_expect); - CHECK (stepStr( 8) == "lev:8 nodes:1 Σw: 2 1.0 Δ2.000 ▿▿ 7.000"_expect); - CHECK (stepStr( 9) == "lev:9 nodes:2 Σw: 2 2.0 Δ1.000 ▿▿ 8.000"_expect); - CHECK (stepStr(10) == "lev:10 nodes:2 Σw: 0 2.0 Δ0.000 ▿▿ 8.000"_expect); - CHECK (stepStr(11) == "lev:11 nodes:2 Σw: 0 2.0 Δ0.000 ▿▿ 8.000"_expect); - CHECK (stepStr(12) == "lev:12 nodes:2 Σw: 2 2.0 Δ1.000 ▿▿ 9.000"_expect); - CHECK (stepStr(13) == "lev:13 nodes:2 Σw: 2 2.0 Δ1.000 ▿▿ 10.000"_expect); - CHECK (stepStr(14) == "lev:14 nodes:2 Σw: 4 2.0 Δ2.000 ▿▿ 12.000"_expect); - CHECK (stepStr(15) == "lev:15 nodes:1 Σw: 0 1.0 Δ0.000 ▿▿ 12.000"_expect); - CHECK (stepStr(16) == "lev:16 nodes:1 Σw: 1 1.0 Δ1.000 ▿▿ 13.000"_expect); - CHECK (stepStr(17) == "lev:17 nodes:1 Σw: 3 1.0 Δ3.000 ▿▿ 16.000"_expect); - CHECK (stepStr(18) == "lev:18 nodes:5 Σw: 0 2.5 Δ0.000 ▿▿ 16.000"_expect); - CHECK (stepStr(19) == "lev:19 nodes:5 Σw:10 2.5 Δ4.000 ▿▿ 20.000"_expect); - CHECK (stepStr(20) == "lev:20 nodes:2 Σw: 5 2.0 Δ2.500 ▿▿ 22.500"_expect); - CHECK (stepStr(21) == "lev:21 nodes:3 Σw: 5 3.0 Δ1.667 ▿▿ 24.167"_expect); - CHECK (stepStr(22) == "lev:22 nodes:6 Σw: 6 3.0 Δ2.000 ▿▿ 26.167"_expect); - CHECK (stepStr(23) == "lev:23 nodes:6 Σw: 6 3.0 Δ2.000 ▿▿ 28.167"_expect); - CHECK (stepStr(24) == "lev:24 nodes:10 Σw: 9 3.3 Δ2.700 ▿▿ 30.867"_expect); - CHECK (stepStr(25) == "lev:25 nodes:2 Σw: 2 2.0 Δ1.000 ▿▿ 31.867"_expect); - CHECK (stepStr(26) == "lev:26 nodes:1 Σw: 1 1.0 Δ1.000 ▿▿ 32.867"_expect); + auto testSetup = + testLoad.setupSchedule(scheduler) + .withLoadTimeBase(LOAD_BASE) + .withJobDeadline(20ms) + .withUpfrontPlanning(); + + auto schedule = testSetup.getScheduleSeq().effuse(); + CHECK (schedule.size() == testLoad.topLevel() + 2); + CHECK (schedule[ 0] == _uTicks(0ms)); + CHECK (schedule[ 1] == _uTicks(1ms)); + CHECK (schedule[26] == _uTicks(26ms)); + CHECK (schedule[27] == _uTicks(27ms)); + + micros = testSetup.launch_and_wait(); +SHOW_EXPR(micros); } diff --git a/tests/vault/gear/test-chain-load.hpp b/tests/vault/gear/test-chain-load.hpp index eabea58a9..bff6abe5f 100644 --- a/tests/vault/gear/test-chain-load.hpp +++ b/tests/vault/gear/test-chain-load.hpp @@ -1640,6 +1640,7 @@ namespace test { microseconds preRoll_{guessPlanningPreroll()}; ManifestationID manID_{}; + std::vector startTimes_{}; std::promise signalDone_{}; std::unique_ptr compuLoad_; @@ -1655,7 +1656,7 @@ namespace test { { schedule_[idx] = scheduler_.defineSchedule(calcJob (idx,level)) .manifestation(manID_) - .startTime (calcStartTime(level)) + .startTime (jobStartTime(level)) .lifeWindow (deadline_) .post(); } @@ -1683,7 +1684,7 @@ namespace test { else scheduler_.defineSchedule(wakeUpJob()) .manifestation (manID_) - .startTime(calcStartTime (levelDone+1)) + .startTime(jobStartTime (levelDone+1)) .lifeWindow(SAFETY_TIMEOUT) .post() .linkToPredecessor (schedule_[lastNodeIDX]) @@ -1699,24 +1700,27 @@ namespace test { size_t firstChunkEndNode = calcNextChunkEnd(0)-1; schedule_.allocate (numNodes); compuLoad_->maybeCalibrate(); - startTime_ = anchorStartTime(); + calcFunctor_.reset (new RandomChainCalcFunctor{chainLoad_.nodes_[0], compuLoad_.get()}); + planFunctor_.reset (new RandomChainPlanFunctor{chainLoad_.nodes_[0], chainLoad_.numNodes_ + ,[this](size_t i, size_t l){ disposeStep(i,l); } + ,[this](auto* p, auto* s) { setDependency(p,s);} + ,[this](size_t n,size_t l, bool w){ continuation(n,l,w); } + }); + startTime_ = anchorSchedule(); scheduler_.seedCalcStream (planningJob(firstChunkEndNode) ,manID_ ,calcLoadHint()); return finished; } + public: ScheduleCtx (TestChainLoad& mother, Scheduler& scheduler) : chainLoad_{mother} , scheduler_{scheduler} , compuLoad_{new ComputationalLoad} - , calcFunctor_{new RandomChainCalcFunctor{chainLoad_.nodes_[0], compuLoad_.get()}} - , planFunctor_{new RandomChainPlanFunctor{chainLoad_.nodes_[0], chainLoad_.numNodes_ - ,[this](size_t i, size_t l){ disposeStep(i,l); } - ,[this](auto* p, auto* s) { setDependency(p,s);} - ,[this](size_t n,size_t l, bool w){ continuation(n,l,w); } - }} + , calcFunctor_{} + , planFunctor_{} { } /** dispose one complete run of the graph into the scheduler @@ -1732,6 +1736,19 @@ namespace test { }); } + auto + getScheduleSeq() + { + if (isnil (startTimes_)) + fillDefaultSchedule(); + + return lib::explore(startTimes_) + .transform([&](Time jobTime) -> Time + { + return jobTime - startTimes_[0]; + }); + } + /* ===== Setter / builders for custom configuration ===== */ @@ -1750,13 +1767,6 @@ namespace test { return move(*this); } - ScheduleCtx&& - withLoadFactor (uint factor_on_levelSpeed) - { - blockLoadFactor_ = factor_on_levelSpeed; - return move(*this); - } - ScheduleCtx&& withChunkSize (size_t nodes_per_chunk) { @@ -1779,6 +1789,25 @@ namespace test { return move(*this); } + ScheduleCtx&& + withAdaptedSchedule(double stressFac =1.0) + { + return move(*this); + } + + ScheduleCtx&& + withUpfrontPlanning() + { + return move(*this); + } + + ScheduleCtx&& + withAnnouncedLoadFactor (uint factor_on_levelSpeed) + { + blockLoadFactor_ = factor_on_levelSpeed; + return move(*this); + } + ScheduleCtx&& withManifestation (ManifestationID manID) { @@ -1864,12 +1893,6 @@ namespace test { }; } - Time - anchorStartTime() - { - return RealClock::now() + _uTicks(preRoll_); - } - microseconds guessPlanningPreroll() { @@ -1890,9 +1913,42 @@ namespace test { } // prevent out-of-bound access Time - calcStartTime(size_t level) + anchorSchedule() { - return startTime_ + Time{level / levelSpeed_}; + Time anchor = RealClock::now() + _uTicks(preRoll_); + if (isnil (startTimes_)) + fillDefaultSchedule(); + size_t numPoints = chainLoad_.topLevel()+2; + ENSURE (startTimes_.size() == numPoints); + for (size_t level=0; level2? nextChunkLevel-2 : 0; - return calcStartTime(nextChunkLevel) - _uTicks(preRoll_); + return jobStartTime(nextChunkLevel) - _uTicks(preRoll_); } }; diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 6ac95396c..50218cbb9 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -107403,10 +107403,10 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + - + @@ -107648,21 +107648,78 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ Idee: logarithmische Suche nach dem breaking point +

+ +
+ +
+ + + +
@@ -110259,19 +110316,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - - - - -

- Idee: logarithmische Suche nach dem breaking point -

- -
-
-
+ +