From 2d1bd2b76592d68e0316b9aa411b6a4ca9d65386 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Mon, 19 Feb 2024 15:58:05 +0100 Subject: [PATCH] Scheduler-test: fix deficiencies in search control mechanism In binary search, in order to establish the invariant initially, a loop is necessary, since a single step might not be sufficient. Moreover, the ongoing adjustments jeopardise detection of the statistical breaking point condition, by causing a negative delta due to gradually approaching the point of convergence -- leading to an ongoing search in a region beyond the actual breaking point. --- src/lib/binary-search.hpp | 16 +++++++----- tests/vault/gear/stress-test-rig.hpp | 5 +++- tests/vault/gear/test-chain-load.hpp | 21 ++++++++------- wiki/thinkPad.ichthyo.mm | 38 +++++++++++++++++++++++++--- 4 files changed, 61 insertions(+), 19 deletions(-) diff --git a/src/lib/binary-search.hpp b/src/lib/binary-search.hpp index a9ead1f6b..28b965863 100644 --- a/src/lib/binary-search.hpp +++ b/src/lib/binary-search.hpp @@ -90,9 +90,11 @@ namespace lib { binarySearch_upper (FUN&& fun, PAR lower, PAR upper, PAR epsilon) { REQUIRE (lower <= upper); - bool hit = fun(upper); - if (not hit) - {// the upper end breaks contract => search above + while (true) + { + bool hit = fun(upper); + if (hit) break; + // the upper end breaks contract => search above PAR len = (upper-lower); lower = upper - len/10; upper = lower + 14*len/10; @@ -106,9 +108,11 @@ namespace lib { binarySearch (FUN&& fun, PAR lower, PAR upper, PAR epsilon) { REQUIRE (lower <= upper); - bool hit = fun(lower); - if (hit) - {// the lower end breaks contract => search below + while (true) + { + bool hit = fun(lower); + if (not hit) break; + // the lower end breaks contract => search below PAR len = (upper-lower); upper = lower + len/10; lower = upper - 14*len/10; diff --git a/tests/vault/gear/stress-test-rig.hpp b/tests/vault/gear/stress-test-rig.hpp index 8934e0b19..69a084fd2 100644 --- a/tests/vault/gear/stress-test-rig.hpp +++ b/tests/vault/gear/stress-test-rig.hpp @@ -155,6 +155,8 @@ namespace test { double expTime{0}; }; + double adjustmentFac{1.0}; + /** prepare the ScheduleCtx for a specifically parametrised test series */ void configureTest (TestSetup& testSetup, double stressFac) @@ -164,7 +166,7 @@ namespace test { .withSchedNotify (CONF::SCHED_NOTIFY) .withSchedDepends(CONF::SCHED_DEPENDS) .withInstrumentation(CONF::INSTRUMENTATION) // side-effect: clear existing statistics - .withAdaptedSchedule(stressFac, CONF::CONCURRENCY); + .withAdaptedSchedule(stressFac, CONF::CONCURRENCY, adjustmentFac); } /** perform a repetition of test runs and compute statistics */ @@ -181,6 +183,7 @@ namespace test { runTime[i] = testSetup.launch_and_wait() / 1000; avgT += runTime[i]; testSetup.adaptEmpirically (stressFac, CONF::CONCURRENCY); + this->adjustmentFac = testSetup.getStressFac() / stressFac; } expT = testSetup.getExpectedEndTime() / 1000; avgT /= CONF::REPETITIONS; diff --git a/tests/vault/gear/test-chain-load.hpp b/tests/vault/gear/test-chain-load.hpp index 46d2b8f89..0dcadf263 100644 --- a/tests/vault/gear/test-chain-load.hpp +++ b/tests/vault/gear/test-chain-load.hpp @@ -1707,10 +1707,10 @@ namespace test { FrameRate levelSpeed_{1, SCHEDULE_LEVEL_STEP}; FrameRate planSpeed_{1, SCHEDULE_PLAN_STEP}; TimeVar nodeExpense_{SCHEDULE_NODE_STEP}; - double stressFact_{1.0}; + double stressFac_{1.0}; bool schedNotify_{SCHED_NOTIFY}; bool schedDepends_{SCHED_DEPENDS}; - uint blockLoadFactor_{2}; + uint blockLoadFac_{2}; size_t chunkSize_{DEFAULT_CHUNKSIZE}; TimeVar startTime_{Time::ANYTIME}; microseconds deadline_{STANDARD_DEADLINE}; @@ -1842,7 +1842,7 @@ namespace test { getExpectedEndTime() { return _raw(startTimes_.back() - startTimes_.front() - + Duration{nodeExpense_}*(chainLoad_.size()/stressFact_)); + + Duration{nodeExpense_}*(chainLoad_.size()/stressFac_)); } auto @@ -1852,6 +1852,9 @@ namespace test { : lib::IncidenceCount::Statistic{}; } + double getStressFac() { return stressFac_; } + + /* ===== Setter / builders for custom configuration ===== */ @@ -1986,7 +1989,7 @@ namespace test { ScheduleCtx&& withAnnouncedLoadFactor (uint factor_on_levelSpeed) { - blockLoadFactor_ = factor_on_levelSpeed; + blockLoadFac_ = factor_on_levelSpeed; return move(*this); } @@ -2084,7 +2087,7 @@ namespace test { FrameRate calcLoadHint() { - return FrameRate{levelSpeed_ * blockLoadFactor_}; + return FrameRate{levelSpeed_ * blockLoadFac_}; } size_t @@ -2112,7 +2115,7 @@ namespace test { fillDefaultSchedule() { size_t numPoints = chainLoad_.topLevel()+2; - stressFact_ = 1.0; + stressFac_ = 1.0; startTimes_.clear(); startTimes_.reserve (numPoints); for (size_t level=0; level 0); - stressFact_ = stressFact; + stressFac_ = stressFact; size_t numPoints = chainLoad_.topLevel()+2; startTimes_.clear(); startTimes_.reserve (numPoints); startTimes_.push_back (Time::ZERO); chainLoad_.levelScheduleSequence (concurrency) - .transform([&](double scheduleFact){ return (scheduleFact/stressFact_) * Offset{1,levelSpeed_};}) + .transform([&](double scheduleFact){ return (scheduleFact/stressFac_) * Offset{1,levelSpeed_};}) .effuse(startTimes_); } @@ -2138,7 +2141,7 @@ namespace test { { ENSURE (level < startTimes_.size()); return startTimes_[level] - + nodeExpense_ * (nodeIDX/stressFact_); + + nodeExpense_ * (nodeIDX/stressFac_); } auto diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index ee34531f1..b23dba96d 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -111617,7 +111617,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -111630,8 +111630,40 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - + + + + + + + + + + + + +

+ denn das Schedule wird ja auf eine nominelle Concurrency ausgelegt +

+ + +
+
+ + + + + + +

+ und diese wird ggfs aus strukturellen Gründen nicht ausgeschöpft +

+ + +
+
+ +