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.
This commit is contained in:
Fischlurch 2024-01-01 20:06:53 +01:00
parent 55cb028abf
commit f4dd309476
3 changed files with 170 additions and 148 deletions

View file

@ -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);
}

View file

@ -1640,6 +1640,7 @@ namespace test {
microseconds preRoll_{guessPlanningPreroll()};
ManifestationID manID_{};
std::vector<TimeVar> startTimes_{};
std::promise<void> signalDone_{};
std::unique_ptr<ComputationalLoad> 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<maxFan>{chainLoad_.nodes_[0], compuLoad_.get()});
planFunctor_.reset (new RandomChainPlanFunctor<maxFan>{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<maxFan>{chainLoad_.nodes_[0], compuLoad_.get()}}
, planFunctor_{new RandomChainPlanFunctor<maxFan>{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; level<numPoints; ++level)
startTimes_[level] += anchor;
return anchor;
}
void
fillDefaultSchedule()
{
size_t numPoints = chainLoad_.topLevel()+2;
startTimes_.clear();
startTimes_.reserve (numPoints);
for (size_t level=0; level<numPoints; ++level)
startTimes_.push_back (level / levelSpeed_);
}
void
fillAdaptedSchedule (double stressFac, uint concurrency)
{
size_t numPoints = chainLoad_.topLevel()+2;
startTimes_.clear();
startTimes_.reserve (numPoints);
chainLoad_.levelScheduleSequence(concurrency).effuse();
}
Time
jobStartTime (size_t level)
{
ENSURE (level < startTimes_.size());
return startTimes_[level];
}
Time
@ -1907,7 +1963,7 @@ namespace test {
lastNodeIDX = min (lastNodeIDX, chainLoad_.size()-1); // prevent out-of-bound access
size_t nextChunkLevel = chainLoad_.nodes_[lastNodeIDX].level;
nextChunkLevel = nextChunkLevel>2? nextChunkLevel-2 : 0;
return calcStartTime(nextChunkLevel) - _uTicks(preRoll_);
return jobStartTime(nextChunkLevel) - _uTicks(preRoll_);
}
};

View file

@ -107403,10 +107403,10 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<linktarget COLOR="#980e34" DESTINATION="ID_451970697" ENDARROW="Default" ENDINCLINATION="163;698;" ID="Arrow_ID_1930824070" SOURCE="ID_1994748011" STARTARROW="None" STARTINCLINATION="-607;42;"/>
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1702944889122" ID="ID_816186443" MODIFIED="1703807949690" TEXT="Berechnung der systematisch-erwartbaren Ausf&#xfc;hrungszeit">
<node COLOR="#338800" CREATED="1702944889122" FOLDED="true" ID="ID_816186443" MODIFIED="1704056444572" TEXT="Berechnung der systematisch-erwartbaren Ausf&#xfc;hrungszeit">
<linktarget COLOR="#618eb4" DESTINATION="ID_816186443" ENDARROW="Default" ENDINCLINATION="-871;-40;" ID="Arrow_ID_888227312" SOURCE="ID_1434946452" STARTARROW="None" STARTINCLINATION="-203;20;"/>
<linktarget COLOR="#5d567f" DESTINATION="ID_816186443" ENDARROW="Default" ENDINCLINATION="-25;77;" ID="Arrow_ID_280715198" SOURCE="ID_1983964457" STARTARROW="None" STARTINCLINATION="-621;-17;"/>
<icon BUILTIN="pencil"/>
<icon BUILTIN="button_ok"/>
<node CREATED="1702944906320" ID="ID_1870513553" MODIFIED="1702944934194" TEXT="per Chain-Load Graph-processing">
<icon BUILTIN="info"/>
<node CREATED="1702945021981" ID="ID_723525598" MODIFIED="1702945026149" TEXT="Level finden"/>
@ -107648,21 +107648,78 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1702945662283" ID="ID_557005311" MODIFIED="1702945685743" TEXT="M&#xf6;glichkeit f&#xfc;r hierauf abstellendes genaues Scheduling">
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1702945698917" ID="ID_617955437" MODIFIED="1702945713108" TEXT="ScheduleCtx stellt dieses Feature bereit">
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1702945662283" ID="ID_557005311" MODIFIED="1704134638849" TEXT="M&#xf6;glichkeit f&#xfc;r hierauf abstellendes genaues Scheduling">
<icon BUILTIN="pencil"/>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1702945698917" ID="ID_617955437" MODIFIED="1704134635631" TEXT="ScheduleCtx stellt dieses Feature bereit">
<icon BUILTIN="pencil"/>
<node CREATED="1703797401009" ID="ID_1091284884" MODIFIED="1703797408236" TEXT="implementiert durch eine LUT"/>
<node CREATED="1703797437806" ID="ID_139711050" MODIFIED="1703797452286" TEXT="welche auch gleich die Integration (Gesamtzeit) mit beinhaltet"/>
<node CREATED="1704131775134" ID="ID_1368289574" MODIFIED="1704131778714" TEXT="Umbauten">
<node COLOR="#435e98" CREATED="1704131779566" ID="ID_665664314" MODIFIED="1704131849268" TEXT="startTime_ bleibt erhalten (zur Dokumentation)">
<icon BUILTIN="yes"/>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1704131789964" ID="ID_1025558471" MODIFIED="1704134610988" TEXT="aber das Schedule wird komplett fertig vorberechnet">
<icon BUILTIN="pencil"/>
<node COLOR="#435e98" CREATED="1704131859763" ID="ID_474855100" MODIFIED="1704134619233" STYLE="fork" TEXT="anchorStartTime() &#x27f6; anchorSchedule()"/>
<node COLOR="#338800" CREATED="1704131877441" ID="ID_1279812512" MODIFIED="1704134622336" TEXT="f&#xfc;llt normalerweise das default-Schedule ein">
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1704131901605" ID="ID_1726719129" MODIFIED="1704134625483" TEXT="ansonsten: schon bef&#xfc;llte Time-Table mit Startzeit beaufschlagen">
<icon BUILTIN="flag-pink"/>
</node>
</node>
<node COLOR="#338800" CREATED="1704131825817" ID="ID_552446029" MODIFIED="1704131842686" TEXT="einen Vector mit den explzitien Startzeitpunkten vorsehen">
<icon BUILTIN="button_ok"/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1702945713771" ID="ID_66050639" MODIFIED="1702945728105" TEXT="verwendet hierzu die Auswertung aus Chain-Load">
<icon BUILTIN="flag-yellow"/>
<node CREATED="1703797265083" ID="ID_117426514" MODIFIED="1703797283385" TEXT="diese kann eine Iterations-Berechnung (one-pass) sein"/>
<node CREATED="1703797286217" ID="ID_1277790232" MODIFIED="1703797356569" TEXT="die Zahl der Level ist bekannt &#x2014; also kann man die in eine fixe Tabelle ziehen"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1704130248910" ID="ID_279203774" MODIFIED="1704130263076" TEXT="Verifikation und Testbarkeit">
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1704130265344" ID="ID_1639859235" MODIFIED="1704130312923" TEXT="effektives Schedule abrufbar machen">
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1704130314106" ID="ID_623101139" MODIFIED="1704130342207" TEXT="initialen pre-roll eigens konfiguieren">
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1704130345454" ID="ID_599280470" MODIFIED="1704130368483" TEXT="initialen pre-roll vom Me&#xdf;ergebnis abziehen">
<icon BUILTIN="flag-yellow"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1704130400942" ID="ID_1446554344" MODIFIED="1704130409312" TEXT="Test-Parametrisierung">
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1702945731584" ID="ID_572123244" MODIFIED="1702945745735" TEXT="stress-Faktor relativ zu diesem Schema">
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1704130423451" ID="ID_828141465" MODIFIED="1704130534983" TEXT="komplett-Planung vorneweg">
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1704130413244" ID="ID_899448993" MODIFIED="1704130422596" TEXT="zus&#xe4;tziches Einzel-Stepping">
<icon BUILTIN="flag-yellow"/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1702946185508" ID="ID_857882482" MODIFIED="1704130713012" TEXT="darauf aufbauend: Stre&#xdf;test-Mechanismus entwicklen">
<icon BUILTIN="flag-yellow"/>
<node CREATED="1702946236869" ID="ID_1475819731" MODIFIED="1704130799415">
<richcontent TYPE="NODE"><html>
<head/>
<body>
<p>
Idee: logarithmische Suche nach dem<i>&#160;breaking point</i>
</p>
</body>
</html></richcontent>
<icon BUILTIN="idea"/>
</node>
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1704130775228" ID="ID_1335708273" MODIFIED="1704130795750" TEXT="Untersuchung: den &#xbb;breaking point&#xab; identifizieren....?">
<icon BUILTIN="help"/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1702945804704" ID="ID_996535642" MODIFIED="1703423856728" TEXT="Beobachtungen aus erweiterten Testl&#xe4;ufen">
<icon BUILTIN="pencil"/>
@ -110259,19 +110316,8 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1702946185508" ID="ID_857882482" MODIFIED="1702946219986" TEXT="darauf aufbauend: Stre&#xdf;test-Mechanismus entwicklen">
<icon BUILTIN="flag-yellow"/>
<node CREATED="1702946236869" ID="ID_1475819731" MODIFIED="1702946254542">
<richcontent TYPE="NODE"><html>
<head/>
<body>
<p>
Idee: logarithmische Suche nach dem<i>&#160;breaking point</i>
</p>
</body>
</html></richcontent>
</node>
</node>
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1704130733890" ID="ID_922119452" MODIFIED="1704130743862" TEXT="Beobachtungen zum Lasttest-Setup">
<icon BUILTIN="hourglass"/>
</node>
</node>
</node>