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.
This commit is contained in:
parent
ff39aed7ea
commit
2d1bd2b765
4 changed files with 61 additions and 19 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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<numPoints; ++level)
|
||||
|
|
@ -2123,13 +2126,13 @@ namespace test {
|
|||
fillAdaptedSchedule (double stressFact, uint concurrency)
|
||||
{
|
||||
REQUIRE (stressFact > 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
|
||||
|
|
|
|||
|
|
@ -111617,7 +111617,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fafe99" COLOR="#fa002a" CREATED="1708349491714" ID="ID_761985075" MODIFIED="1708349513895" TEXT="Nachjustieren stört die Ablaufsteuerung">
|
||||
<node COLOR="#435e98" CREATED="1708349491714" ID="ID_761985075" MODIFIED="1708354204131" TEXT="Nachjustieren stört die Ablaufsteuerung">
|
||||
<icon BUILTIN="broken-line"/>
|
||||
<node CREATED="1708349515240" ID="ID_310788329" MODIFIED="1708349569666" TEXT="Zeiten nehmen innerhalb der Testserie jeweils zu"/>
|
||||
<node CREATED="1708349570374" ID="ID_1868657338" MODIFIED="1708349595735" TEXT="die »expected time« wird vom letztlich erreichten Schedule abgenommen"/>
|
||||
|
|
@ -111630,8 +111630,40 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node CREATED="1708352301762" ID="ID_1952936030" MODIFIED="1708352316052" TEXT="die Vor-Phase hat nur einmal geprüft und nachjustiert"/>
|
||||
<node CREATED="1708352316775" ID="ID_507913615" MODIFIED="1708352327465" TEXT="damit war die Invariante schon zu Beginn verletzt"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1708352337965" ID="ID_872133168" MODIFIED="1708352355731" TEXT="Idee: den zuletzt verwendeten Form-Faktor als Startpunkt merken">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1708352337965" ID="ID_872133168" MODIFIED="1708354202022" TEXT="Idee: den zuletzt verwendeten Form-Faktor als Startpunkt merken">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1708353494162" ID="ID_1417741022" MODIFIED="1708353524083" TEXT="Fraglich ob Einrechnen der Concurrency sinnvoll ist">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1708353529389" ID="ID_1264074130" MODIFIED="1708353581342">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
denn das Schedule wird ja auf eine <i>nominelle </i>Concurrency ausgelegt
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1708353549722" ID="ID_739919619" MODIFIED="1708353588560">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
und diese wird ggfs aus <i>strukturellen Gründen </i>nicht ausgeschöpft
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1708353589901" ID="ID_753673138" MODIFIED="1708353635590" TEXT="was dann mithin nicht als Leistungsreserve gedeutet werden darf">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue