Scheduler: implement capacity redistribution scheme
wow... that was conceptually challenging, yet dead easy to implement
This commit is contained in:
parent
6ccb6540e6
commit
69fb77246e
4 changed files with 161 additions and 37 deletions
|
|
@ -169,7 +169,7 @@ namespace gear {
|
|||
|
||||
/** classification of time horizon for scheduling */
|
||||
static Capacity
|
||||
classifyCapacity (Offset off)
|
||||
classifyTimeHorizon (Offset off)
|
||||
{
|
||||
if (off > SLEEP_HORIZON) return IDLETIME;
|
||||
if (off > WORK_HORIZON) return WORKTIME;
|
||||
|
|
@ -179,23 +179,29 @@ namespace gear {
|
|||
}
|
||||
|
||||
|
||||
Capacity
|
||||
markOutgoingCapacity (Time head, Time now)
|
||||
{
|
||||
auto horizon = classifyTimeHorizon (Offset{head - now});
|
||||
return horizon > SPINTIME
|
||||
and not tendedNext(head)? TENDNEXT
|
||||
: horizon;
|
||||
}
|
||||
|
||||
Capacity
|
||||
markIncomingCapacity (Time head, Time now)
|
||||
{
|
||||
return classifyTimeHorizon (Offset{head - now})
|
||||
> NEARTIME ? IDLETIME
|
||||
: markOutgoingCapacity(head,now);
|
||||
}
|
||||
|
||||
|
||||
Time
|
||||
scatteredDelayTime (Capacity capacity)
|
||||
{
|
||||
UNIMPLEMENTED ("establish a randomised targeted delay time");
|
||||
}
|
||||
|
||||
Capacity
|
||||
incomingCapacity (Time head, Time now)
|
||||
{
|
||||
UNIMPLEMENTED ("decide how to use incoming free work capacity");
|
||||
}
|
||||
|
||||
Capacity
|
||||
outgoingCapacity (Time head, Time now)
|
||||
{
|
||||
UNIMPLEMENTED ("decide how to use outgoing free work capacity");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -308,14 +308,14 @@ namespace gear {
|
|||
|
||||
return WorkerInstruction{}
|
||||
.performStep([&]{ return scatteredDelay(
|
||||
loadControl_.incomingCapacity (head,now));
|
||||
loadControl_.markIncomingCapacity (head,now));
|
||||
})
|
||||
.performStep([&]{
|
||||
Activity* act = layer2_.findWork (layer1_,now);
|
||||
return ctx.post (now, act, ctx);
|
||||
})
|
||||
.performStep([&]{ return scatteredDelay(
|
||||
loadControl_.outgoingCapacity (head,now));
|
||||
loadControl_.markOutgoingCapacity (head,now));
|
||||
})
|
||||
;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,8 +64,9 @@ namespace test {
|
|||
run (Arg)
|
||||
{
|
||||
simpleUsage();
|
||||
classifyTimings();
|
||||
classifyHorizon();
|
||||
tendNextActivity();
|
||||
classifyCapacity();
|
||||
walkingDeadline();
|
||||
setupLalup();
|
||||
}
|
||||
|
|
@ -93,7 +94,7 @@ namespace test {
|
|||
* @todo WIP 10/23 ✔ define ⟶ ✔ implement
|
||||
*/
|
||||
void
|
||||
classifyTimings()
|
||||
classifyHorizon()
|
||||
{
|
||||
Time next{0,10};
|
||||
|
||||
|
|
@ -105,16 +106,16 @@ namespace test {
|
|||
Time t31{t3 + ut};
|
||||
Time t4{next - NOW_HORIZON};
|
||||
|
||||
CHECK (Capacity::IDLETIME == LoadController::classifyCapacity (Offset{next - ut }));
|
||||
CHECK (Capacity::IDLETIME == LoadController::classifyCapacity (Offset{next - t1 }));
|
||||
CHECK (Capacity::WORKTIME == LoadController::classifyCapacity (Offset{next - t2 }));
|
||||
CHECK (Capacity::WORKTIME == LoadController::classifyCapacity (Offset{next - t21}));
|
||||
CHECK (Capacity::NEARTIME == LoadController::classifyCapacity (Offset{next - t3 }));
|
||||
CHECK (Capacity::NEARTIME == LoadController::classifyCapacity (Offset{next - t31}));
|
||||
CHECK (Capacity::SPINTIME == LoadController::classifyCapacity (Offset{next - t4 }));
|
||||
CHECK (Capacity::IDLETIME == LoadController::classifyTimeHorizon (Offset{next - ut }));
|
||||
CHECK (Capacity::IDLETIME == LoadController::classifyTimeHorizon (Offset{next - t1 }));
|
||||
CHECK (Capacity::WORKTIME == LoadController::classifyTimeHorizon (Offset{next - t2 }));
|
||||
CHECK (Capacity::WORKTIME == LoadController::classifyTimeHorizon (Offset{next - t21}));
|
||||
CHECK (Capacity::NEARTIME == LoadController::classifyTimeHorizon (Offset{next - t3 }));
|
||||
CHECK (Capacity::NEARTIME == LoadController::classifyTimeHorizon (Offset{next - t31}));
|
||||
CHECK (Capacity::SPINTIME == LoadController::classifyTimeHorizon (Offset{next - t4 }));
|
||||
|
||||
CHECK (Capacity::DISPATCH == LoadController::classifyCapacity (Offset::ZERO ));
|
||||
CHECK (Capacity::DISPATCH == LoadController::classifyCapacity (Offset{t4 - next }));
|
||||
CHECK (Capacity::DISPATCH == LoadController::classifyTimeHorizon (Offset::ZERO ));
|
||||
CHECK (Capacity::DISPATCH == LoadController::classifyTimeHorizon (Offset{t4 - next }));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -159,6 +160,77 @@ namespace test {
|
|||
|
||||
|
||||
|
||||
/** @test verify allocation decision for free capacity
|
||||
* - due and overdue Activities are prioritised
|
||||
* - keep spinning when next Activity to schedule is very close
|
||||
* - otherwise, priority is to tend for the next known Activity
|
||||
* - beyond that, free capacity is redistributed according to horizon
|
||||
* - for incoming free capacity there is a preference to keep it sleeping,
|
||||
* to allow for disposing of excess capacity after extended sleep time
|
||||
* @todo WIP 10/23 ✔ define ⟶ ✔ implement
|
||||
*/
|
||||
void
|
||||
classifyCapacity()
|
||||
{
|
||||
BlockFlowAlloc bFlow;
|
||||
LoadController lctrl{bFlow};
|
||||
|
||||
Time next{0,10};
|
||||
|
||||
Time ut{1,0};
|
||||
Time t1{0,9};
|
||||
Time t2{next - SLEEP_HORIZON};
|
||||
Time t3{next - WORK_HORIZON};
|
||||
Time t4{next - NOW_HORIZON};
|
||||
Time t5{next + ut}; // ╭────────────── next Activity at scheduler head
|
||||
// │ ╭──────── current time of evaluation
|
||||
// Time `next` has not been tended yet... // ▼ ▼
|
||||
CHECK (Capacity::TENDNEXT == lctrl.markOutgoingCapacity (next, ut ));
|
||||
|
||||
// but after marking `next` as tended, capacity can be directed elsewhere
|
||||
lctrl.tendNext (next);
|
||||
CHECK (Capacity::IDLETIME == lctrl.markOutgoingCapacity (next, ut ));
|
||||
|
||||
CHECK (Capacity::IDLETIME == lctrl.markOutgoingCapacity (next, t1 ));
|
||||
CHECK (Capacity::WORKTIME == lctrl.markOutgoingCapacity (next, t2 ));
|
||||
CHECK (Capacity::NEARTIME == lctrl.markOutgoingCapacity (next, t3 ));
|
||||
CHECK (Capacity::SPINTIME == lctrl.markOutgoingCapacity (next, t4 ));
|
||||
|
||||
CHECK (Capacity::DISPATCH == lctrl.markOutgoingCapacity (next,next));
|
||||
CHECK (Capacity::DISPATCH == lctrl.markOutgoingCapacity (next, t5 ));
|
||||
|
||||
CHECK (Capacity::IDLETIME == lctrl.markIncomingCapacity (next, ut ));
|
||||
CHECK (Capacity::IDLETIME == lctrl.markIncomingCapacity (next, t1 ));
|
||||
CHECK (Capacity::IDLETIME == lctrl.markIncomingCapacity (next, t2 ));
|
||||
CHECK (Capacity::NEARTIME == lctrl.markIncomingCapacity (next, t3 ));
|
||||
CHECK (Capacity::SPINTIME == lctrl.markIncomingCapacity (next, t4 ));
|
||||
|
||||
CHECK (Capacity::DISPATCH == lctrl.markIncomingCapacity (next,next));
|
||||
CHECK (Capacity::DISPATCH == lctrl.markIncomingCapacity (next, t5 ));
|
||||
|
||||
// tend-next works in limited ways also on incoming capacity
|
||||
lctrl.tendNext (Time::NEVER);
|
||||
CHECK (Capacity::IDLETIME == lctrl.markIncomingCapacity (next, ut ));
|
||||
CHECK (Capacity::IDLETIME == lctrl.markIncomingCapacity (next, t1 ));
|
||||
CHECK (Capacity::IDLETIME == lctrl.markIncomingCapacity (next, t2 ));
|
||||
CHECK (Capacity::TENDNEXT == lctrl.markIncomingCapacity (next, t3 ));
|
||||
CHECK (Capacity::SPINTIME == lctrl.markIncomingCapacity (next, t4 ));
|
||||
|
||||
CHECK (Capacity::DISPATCH == lctrl.markIncomingCapacity (next,next));
|
||||
CHECK (Capacity::DISPATCH == lctrl.markIncomingCapacity (next, t5 ));
|
||||
|
||||
// while being used rather generously on outgoing capacity
|
||||
CHECK (Capacity::TENDNEXT == lctrl.markOutgoingCapacity (next, ut ));
|
||||
CHECK (Capacity::TENDNEXT == lctrl.markOutgoingCapacity (next, t1 ));
|
||||
CHECK (Capacity::TENDNEXT == lctrl.markOutgoingCapacity (next, t2 ));
|
||||
CHECK (Capacity::TENDNEXT == lctrl.markOutgoingCapacity (next, t3 ));
|
||||
CHECK (Capacity::SPINTIME == lctrl.markOutgoingCapacity (next, t4 ));
|
||||
|
||||
CHECK (Capacity::DISPATCH == lctrl.markOutgoingCapacity (next,next));
|
||||
CHECK (Capacity::DISPATCH == lctrl.markOutgoingCapacity (next, t5 ));
|
||||
}
|
||||
|
||||
|
||||
/** @test TODO
|
||||
* @todo WIP 10/23 🔁 define ⟶ implement
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -82004,9 +82004,9 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1697768205409" ID="ID_489957180" MODIFIED="1697768215224" TEXT="mit dem Load-Controller verbinden">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1697808041495" ID="ID_492054934" MODIFIED="1698004006239" TEXT="die Work-Function zusammenstellen">
|
||||
<node COLOR="#338800" CREATED="1697808041495" ID="ID_492054934" MODIFIED="1698079204212" TEXT="die Work-Function zusammenstellen">
|
||||
<linktarget COLOR="#7779a3" DESTINATION="ID_492054934" ENDARROW="Default" ENDINCLINATION="-814;62;" ID="Arrow_ID_817672667" SOURCE="ID_391492289" STARTARROW="None" STARTINCLINATION="1393;-112;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1698004010478" ID="ID_1609383346" MODIFIED="1698009701573" TEXT="Schritte">
|
||||
<icon BUILTIN="list"/>
|
||||
<node CREATED="1698004022584" ID="ID_1953987297" MODIFIED="1698009688618" TEXT="Kapazität feststellen">
|
||||
|
|
@ -82256,7 +82256,9 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
<node CREATED="1697934020751" ID="ID_1139695361" MODIFIED="1697934032818" TEXT="wenn nichts mehr passiert, kann er sich deaktivieren">
|
||||
<node CREATED="1697935611257" ID="ID_436115424" MODIFIED="1697935652768" TEXT="zunächst werden die Worker schlafen geschickt">
|
||||
<node CREATED="1697935685080" ID="ID_1125666331" MODIFIED="1697935700776" TEXT="Vorsicht: vorausschauend handeln"/>
|
||||
<node CREATED="1697935685080" ID="ID_1125666331" MODIFIED="1698079245795" TEXT="Vorsicht: vorausschauend handeln">
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node CREATED="1697935701613" ID="ID_601914515" MODIFIED="1697935798105" TEXT="der Schlaf-Zyklus soll relativ lang sein">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
|
|
@ -82283,6 +82285,11 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
<node CREATED="1697939007756" ID="ID_1814410393" MODIFIED="1697939068200" TEXT="idle-Time ⟶ schlafen schicken"/>
|
||||
</node>
|
||||
<node CREATED="1698079285650" ID="ID_1194794962" MODIFIED="1698079299495" TEXT="freie Kapazität „fließt“">
|
||||
<node CREATED="1698079326197" ID="ID_1517718994" MODIFIED="1698079334136" TEXT="ein Teil setzt sich ab"/>
|
||||
<node CREATED="1698079334681" ID="ID_1880078243" MODIFIED="1698079345414" TEXT="aber auch von den Schläfern gibt es einen Rückstrom"/>
|
||||
<node CREATED="1698079346272" ID="ID_1708377480" MODIFIED="1698079371100" TEXT="Konzentration je nach Arbeitsdichte"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1697935657451" ID="ID_1200603474" MODIFIED="1697935676437" TEXT="diese beenden sich dann nach einiger Zeit von selbst">
|
||||
|
|
@ -82500,7 +82507,9 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1697982488254" ID="ID_1839282150" MODIFIED="1697982492138" TEXT="incomingCapacity"/>
|
||||
<node CREATED="1697982492782" ID="ID_1050821331" MODIFIED="1697982497641" TEXT="outgoingCapacity"/>
|
||||
<node CREATED="1697982575563" ID="ID_1770606344" MODIFIED="1697982580261" TEXT="dispatchedCapacity"/>
|
||||
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1697982575563" ID="ID_1770606344" MODIFIED="1698078325355" TEXT="dispatchedCapacity">
|
||||
<icon BUILTIN="help"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1697982589257" HGAP="11" ID="ID_1783139757" MODIFIED="1697982614929" TEXT="pro-forma in den LoadController legen" VSHIFT="9">
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
|
|
@ -82609,20 +82618,44 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node CREATED="1697983591252" ID="ID_777679840" MODIFIED="1697983596782" TEXT="liefert activity::PROC"/>
|
||||
<node CREATED="1697983597603" ID="ID_1430310887" MODIFIED="1697983605069" TEXT="führt die Verzögerung unmittelbar aus"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1697983546449" ID="ID_1801117774" MODIFIED="1697983563416" TEXT="scatteredDelayTime()">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1697983546449" ID="ID_1801117774" MODIFIED="1698079545463" TEXT="scatteredDelayTime()">
|
||||
<icon BUILTIN="forward"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1698003862646" ID="ID_402749835" MODIFIED="1698003871297" TEXT="Integration mit...">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1698003871908" ID="ID_391492289" MODIFIED="1698003962732" TEXT="work-Function">
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1698003871908" ID="ID_391492289" MODIFIED="1698079188892" TEXT="work-Function">
|
||||
<arrowlink COLOR="#7779a3" DESTINATION="ID_492054934" ENDARROW="Default" ENDINCLINATION="-814;62;" ID="Arrow_ID_817672667" STARTARROW="None" STARTINCLINATION="1393;-112;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1698019149574" HGAP="40" ID="ID_982468485" MODIFIED="1698019158970" TEXT="Fallunterscheidung" VSHIFT="21">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1698019149574" HGAP="40" ID="ID_982468485" MODIFIED="1698078066168" TEXT="Fallunterscheidung" VSHIFT="21">
|
||||
<linktarget COLOR="#378f79" DESTINATION="ID_982468485" ENDARROW="Default" ENDINCLINATION="-84;-47;" ID="Arrow_ID_902782295" SOURCE="ID_1677472042" STARTARROW="None" STARTINCLINATION="31;94;"/>
|
||||
<node CREATED="1698019164588" ID="ID_1369255451" MODIFIED="1698019165160" TEXT="incomingCapacity"/>
|
||||
<node CREATED="1698019170228" ID="ID_311501577" MODIFIED="1698019170871" TEXT="outgoingCapacity"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1698019170228" ID="ID_311501577" MODIFIED="1698078071150" TEXT="outgoingCapacity">
|
||||
<node CREATED="1698078074777" ID="ID_1807447539" MODIFIED="1698078181537" TEXT="Basis-Schema ">
|
||||
<icon BUILTIN="info"/>
|
||||
</node>
|
||||
<node CREATED="1698078079896" ID="ID_608362501" MODIFIED="1698078184283" TEXT="fällige Termine haben Vorrang">
|
||||
<icon BUILTIN="full-1"/>
|
||||
</node>
|
||||
<node CREATED="1698078093672" ID="ID_1701101602" MODIFIED="1698078186423" TEXT="im Nah-Intervall wird gespinnt">
|
||||
<icon BUILTIN="full-2"/>
|
||||
</node>
|
||||
<node CREATED="1698078109744" ID="ID_865429598" MODIFIED="1698078188571" TEXT="tend-Next-Mechanismus">
|
||||
<icon BUILTIN="full-3"/>
|
||||
</node>
|
||||
<node CREATED="1698078151042" ID="ID_558277791" MODIFIED="1698078191203" TEXT="Redistribution im Horizont">
|
||||
<icon BUILTIN="full-4"/>
|
||||
</node>
|
||||
<node CREATED="1698078223097" ID="ID_597306541" MODIFIED="1698078227054" TEXT="Schlafen">
|
||||
<icon BUILTIN="full-5"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1698019164588" ID="ID_1369255451" MODIFIED="1698019165160" TEXT="incomingCapacity">
|
||||
<node CREATED="1698078198356" ID="ID_187052761" MODIFIED="1698078221980" TEXT="Schlafen hat Vorrang"/>
|
||||
<node CREATED="1698078230223" ID="ID_956821068" MODIFIED="1698078245813" TEXT="aber fällige Temine und Nach-Intervall werden bedient"/>
|
||||
<node CREATED="1698078250230" ID="ID_69285927" MODIFIED="1698078267335" TEXT="tend-Next findet nur in NEARTIME statt"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -82632,6 +82665,13 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<icon BUILTIN="pencil"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1698078367419" HGAP="-36" ID="ID_1532750540" MODIFIED="1698079050460" TEXT="offene Fragen" VSHIFT="11">
|
||||
<linktarget COLOR="#713d56" DESTINATION="ID_1532750540" ENDARROW="Default" ENDINCLINATION="-2344;353;" ID="Arrow_ID_1939324405" SOURCE="ID_161990356" STARTARROW="None" STARTINCLINATION="1495;112;"/>
|
||||
<icon BUILTIN="bell"/>
|
||||
<node CREATED="1698078395346" ID="ID_1995310118" MODIFIED="1698078418081" TEXT="ist die probabilistische Kapazitätsverteilung ausreichend, um Aussetzer zu verhindern?"/>
|
||||
<node CREATED="1698078423734" ID="ID_588175161" MODIFIED="1698078714099" TEXT="bringt das Spinning im Nah-Bereich überhaupt etwas (oder schadet es gar?)"/>
|
||||
<node CREATED="1698078720726" ID="ID_690302845" MODIFIED="1698078865023" TEXT="muß incomingCapacity überhaupt am tend-Next teilnehmen?"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1687738213842" ID="ID_683259902" MODIFIED="1687738250423" TEXT="Payload: ActOrder">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
|
|
@ -91094,6 +91134,12 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1698079023246" ID="ID_1404968698" MODIFIED="1698079027257" TEXT="Diskussion und Fragen">
|
||||
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1698078896511" ID="ID_161990356" MODIFIED="1698079050460" TEXT="Fragen zum Scheduler Load-Control">
|
||||
<arrowlink COLOR="#713d56" DESTINATION="ID_1532750540" ENDARROW="Default" ENDINCLINATION="-2344;353;" ID="Arrow_ID_1939324405" STARTARROW="None" STARTINCLINATION="1495;112;"/>
|
||||
<icon BUILTIN="hourglass"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue