Scheduler: solve the initialisation of WorkForce
Notably I wanted an entirely static and direct binding to the internals of the Scheduler, which can be completely inlined. The chosen solution also has the benefit of making the back-reference to the Scheduler explicitly visible to the reader. This is relevant, since the Config-Subobject is *copied* into each Worker instance.
This commit is contained in:
parent
74c97614b3
commit
26b2e6f1bd
3 changed files with 108 additions and 22 deletions
|
|
@ -63,9 +63,17 @@ namespace gear {
|
|||
// using util::isnil;
|
||||
// using std::string;
|
||||
|
||||
namespace { // Scheduler default config
|
||||
|
||||
const auto IDLE_WAIT = 20ms;
|
||||
const size_t DISMISS_CYCLES = 100;
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule and coordinate render activities.
|
||||
|
||||
|
||||
|
||||
/******************************************************//**
|
||||
* »Scheduler-Service« : coordinate render activities.
|
||||
* @todo WIP-WIP 6/2023
|
||||
* @see BlockFlow
|
||||
* @see SchedulerUsage_test
|
||||
|
|
@ -73,23 +81,30 @@ namespace gear {
|
|||
class Scheduler
|
||||
: util::NonCopyable
|
||||
{
|
||||
using Setup = work::Config; ////////////////////////////////////////////////////OOO actually need subclass to attach the work-function
|
||||
/** Binding of worker callbacks to the scheduler implementation */
|
||||
struct Setup : work::Config
|
||||
{
|
||||
Scheduler& scheduler;
|
||||
activity::Proc doWork() { return scheduler.getWork(); }
|
||||
void finalHook (bool _) { scheduler.handleWorkerTermination(_);}
|
||||
};
|
||||
|
||||
|
||||
SchedulerInvocation layer1_;
|
||||
SchedulerCommutator layer2_;
|
||||
// WorkForce<Setup> workForce_;
|
||||
WorkForce<Setup> workForce_;
|
||||
|
||||
ActivityLang activityLang_;
|
||||
LoadController loadControl_;
|
||||
EngineObserver& engineObserver_;
|
||||
|
||||
|
||||
public:
|
||||
explicit
|
||||
Scheduler (BlockFlowAlloc& activityAllocator
|
||||
,EngineObserver& engineObserver)
|
||||
: layer1_{}
|
||||
, layer2_{}
|
||||
// , workForce_{connectWorkers()}
|
||||
, workForce_{Setup{IDLE_WAIT, DISMISS_CYCLES, *this}}
|
||||
, activityLang_{activityAllocator}
|
||||
, loadControl_{activityAllocator}
|
||||
, engineObserver_{engineObserver}
|
||||
|
|
@ -139,17 +154,17 @@ namespace gear {
|
|||
/**
|
||||
*
|
||||
*/
|
||||
void
|
||||
activity::Proc
|
||||
getWork()
|
||||
{
|
||||
UNIMPLEMENTED("the Worker-Funkction");
|
||||
}
|
||||
|
||||
private:
|
||||
Setup
|
||||
connectWorkers()
|
||||
void
|
||||
handleWorkerTermination (bool isFailure)
|
||||
{
|
||||
UNIMPLEMENTED("build Worker pool operational setup");
|
||||
UNIMPLEMENTED("die harder");
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -72,12 +72,12 @@ namespace gear {
|
|||
using std::move;
|
||||
using std::atomic;
|
||||
using util::unConst;
|
||||
using std::chrono::milliseconds;
|
||||
using std::chrono_literals::operator ""ms;
|
||||
using std::this_thread::sleep_for;
|
||||
|
||||
|
||||
namespace work { ///< Details of WorkForce (worker pool) implementation
|
||||
using std::chrono::milliseconds;
|
||||
using std::chrono_literals::operator ""ms;
|
||||
|
||||
using SIG_WorkFun = activity::Proc(void); ///< config should define a callable with this signature to perform work
|
||||
using SIG_FinalHook = void(bool); ///< config should define callable invoked at exit (argument: isFailure)
|
||||
|
|
@ -94,7 +94,6 @@ namespace gear {
|
|||
struct Config
|
||||
{
|
||||
static const size_t COMPUTATION_CAPACITY;
|
||||
const size_t EXPECTED_MAX_POOL = 1.5*COMPUTATION_CAPACITY;
|
||||
|
||||
const milliseconds IDLE_WAIT = 20ms;
|
||||
const size_t DISMISS_CYCLES = 100;
|
||||
|
|
|
|||
|
|
@ -81765,15 +81765,44 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1693172098402" ID="ID_671792975" MODIFIED="1697553002393" TEXT="Dependency-Injection">
|
||||
<icon BUILTIN="help"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1693841227130" ID="ID_1537960830" MODIFIED="1697675265270" TEXT="WorkForce einbinden">
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1693841227130" ID="ID_1537960830" MODIFIED="1697818566052" TEXT="WorkForce einbinden">
|
||||
<arrowlink COLOR="#397cb2" DESTINATION="ID_987966047" ENDARROW="Default" ENDINCLINATION="-962;-41;" ID="Arrow_ID_818972822" STARTARROW="None" STARTINCLINATION="-609;73;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1697768180196" ID="ID_1541537637" MODIFIED="1697768202330" TEXT="work::Config konstruieren">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1697768180196" ID="ID_1541537637" MODIFIED="1697818152259" TEXT="work::Config konstruieren">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Schwere Geburt...
|
||||
</p>
|
||||
<p>
|
||||
Irgendwie hatte sich bei mir die Idee mit den Lambdas so festgefressen — obwohl ich doch schon eingesehen hatte, daß C++ in der Hinsicht (aus gutem Grund) sehr konsequent ist, und keine Hintertür bietet, um Laufzeit-Bindigns in die statische Ebene „zu schmuggeln“. Was mich dann aber auch extrem gestört hat, waren die std::function-Felder, in die man die Lambdas speichern müßte. Es wäre nämlich eine andere Lösung denkbar, bei der diese Function-Objekte schon in der Basis-Config für die WorkForce enthalten sind; damit wäre das Design auch komplett festgelgt (und der Test würde sogar einfacher). Trotzdem habe ich eine Abneigung gegen diese Function-Objekte, weil sie eben komplett unnötig sind, da es sich effektiv um ein <i>statisches Binding </i>handeln sollte. Und das war dann das rettende Stichwort: dann definiert man eben diese Binding-Forwarder als statische Funktionen in einer nested Class, und macht die Rückreferenz auf den Scheduler explizit. Und mit Aggregat-Initialisierung kann man dann sogar noch die Definition des Konstruktors auslassen
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<arrowlink COLOR="#f3fea4" DESTINATION="ID_983915877" ENDARROW="Default" ENDINCLINATION="1743;-58;" ID="Arrow_ID_529465664" STARTARROW="None" STARTINCLINATION="822;78;"/>
|
||||
<icon BUILTIN="smiley-angry"/>
|
||||
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1697810722994" HGAP="47" ID="ID_720864528" MODIFIED="1697810766219" TEXT="später wird hier eine globale Engine-Parametrisierung einfließen" VSHIFT="-6">
|
||||
<edge COLOR="#ffdaa4"/>
|
||||
<icon BUILTIN="hourglass"/>
|
||||
</node>
|
||||
</node>
|
||||
<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="1697808055694" TEXT="mit der Work-Function abstimmen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1697808056565" ID="ID_10043675" MODIFIED="1697808062704" TEXT="Fehlerbehandlung bedenken">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1697808069219" ID="ID_1793076416" MODIFIED="1697808179770" TEXT="Grooming-Token garantiert freigeben">
|
||||
<arrowlink COLOR="#fe3a8d" DESTINATION="ID_240227471" ENDARROW="Default" ENDINCLINATION="1819;-50;" ID="Arrow_ID_1740525983" STARTARROW="None" STARTINCLINATION="221;16;"/>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#d2beaf" COLOR="#6920c0" CREATED="1697808219247" ID="ID_1041283707" MODIFIED="1697808253529" TEXT="ungeklärt: HALT an einzelne Worker?">
|
||||
<icon BUILTIN="bell"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1697675135117" ID="ID_880133050" MODIFIED="1697675148836" TEXT="ActivityLang + BlockFlow">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
|
|
@ -81799,6 +81828,19 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1697663918107" ID="ID_210862409" MODIFIED="1697675123151" TEXT="Load-Controller vorsehen">
|
||||
<linktarget COLOR="#75769b" DESTINATION="ID_210862409" ENDARROW="Default" ENDINCLINATION="-667;72;" ID="Arrow_ID_1800712901" SOURCE="ID_464175339" STARTARROW="None" STARTINCLINATION="-540;37;"/>
|
||||
<icon BUILTIN="flag-pink"/>
|
||||
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1697808322602" ID="ID_1787549088" MODIFIED="1697808340997" TEXT="Entwickelt sich wohl in Richtung einer Steuerzentrale">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1697808351773" ID="ID_1501083047" MODIFIED="1697808428660" TEXT="Leistungen">
|
||||
<icon BUILTIN="info"/>
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1697808357389" ID="ID_1714344789" MODIFIED="1697808392696" TEXT="Signal-fusion in gemeinsamen Load-Indikator">
|
||||
<icon BUILTIN="bell"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1697808402431" ID="ID_1499932709" MODIFIED="1697808419725" TEXT="beobachtet / weiß von der WorkForce-Stärke">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1693172069235" ID="ID_1573845677" MODIFIED="1697675305351" TEXT="Layer-1: SchedulerInvocation"/>
|
||||
|
|
@ -84509,7 +84551,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node CREATED="1693792157926" ID="ID_429801566" MODIFIED="1693792193345" TEXT="komplett heruntergeregelt ⟹ Render-Engine deaktiviert"/>
|
||||
<node CREATED="1693792250942" ID="ID_1000686206" MODIFIED="1693792285653" TEXT="Obergrenze ≙ Hardware-concurrency * Provisionierungs-Faktor"/>
|
||||
<node CREATED="1693792308542" ID="ID_1678880734" MODIFIED="1693792318777" TEXT="Herunterregeln erfolgt kooperativ"/>
|
||||
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1693792585515" FOLDED="true" ID="ID_464175339" MODIFIED="1693792605896" TEXT="geplant: dynamische Kapazitätsregelung">
|
||||
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1693792585515" FOLDED="true" ID="ID_464175339" MODIFIED="1697806953842" TEXT="geplant: dynamische Kapazitätsregelung">
|
||||
<arrowlink COLOR="#75769b" DESTINATION="ID_210862409" ENDARROW="Default" ENDINCLINATION="-667;72;" ID="Arrow_ID_1800712901" STARTARROW="None" STARTINCLINATION="-540;37;"/>
|
||||
<icon BUILTIN="hourglass"/>
|
||||
<node CREATED="1693792629986" ID="ID_1269240792" MODIFIED="1693792648043" TEXT="nur mindest-Stärke läuft"/>
|
||||
|
|
@ -84520,10 +84562,21 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node CREATED="1693792715966" ID="ID_717442289" MODIFIED="1697663859531" TEXT="die "pull-work"-Funkton wird vom Scheduler-Service bereitgestellt"/>
|
||||
<node CREATED="1697663861416" ID="ID_558783590" MODIFIED="1697663878469" TEXT="...ist aber implementiert mit Funktionalität von Layer-2"/>
|
||||
<node CREATED="1693792744114" ID="ID_1037530409" MODIFIED="1693792754452" TEXT="die Schlaf-Periode ist ein (steuer)-Parameter"/>
|
||||
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1693792760213" FOLDED="true" ID="ID_1223151647" MODIFIED="1694304517016" TEXT="ggfs leicht randomisiert">
|
||||
<icon BUILTIN="hourglass"/>
|
||||
<node COLOR="#5b280f" CREATED="1693792760213" ID="ID_1223151647" MODIFIED="1697810671367" TEXT="ggfs leicht randomisiert">
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
<node CREATED="1693792791729" ID="ID_649360495" MODIFIED="1693792804966" TEXT="Einschätzung: das genügt um Contention zu vermeiden"/>
|
||||
<node CREATED="1693792900758" ID="ID_1613781033" MODIFIED="1693792927222" TEXT="Vorraussetzung: Arbeitsphase >> Management-Phase"/>
|
||||
<node CREATED="1697810446431" ID="ID_1168022862" MODIFIED="1697810667289" TEXT="sollte sogar ohne Randomisierung keine Probleme geben">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Denn jeder Aufruf des Fork-Funktors wird unterschiedlich lang dauern. Und selbst wenn alle Worker idle sind: dann gibt es bei der ersten Runde die Mega-Contention, und danach liegen die Wartezyklen aller Worker leicht gestaffelt. Contention wäre nur dann ein Problem, wenn jemand, der <i>arbeiten könnte, </i>vom Arbeiten abgehalten wird.
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1697810678448" ID="ID_1023870178" MODIFIED="1697810695263" TEXT="daher ist IDLE_WAIT nun ein beim Start festgelegter Konfig-Parameter"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -84666,7 +84719,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1694130437980" ID="ID_1626878133" MODIFIED="1694130721769" TEXT="die Code-Organisation spricht für den Scheduler-Layer-2">
|
||||
<node COLOR="#344951" CREATED="1694130437980" ID="ID_1626878133" MODIFIED="1697807837200" TEXT="die Code-Organisation spricht für den Scheduler-Layer-2">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
|
|
@ -84675,6 +84728,23 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<node BACKGROUND_COLOR="#c8c0b6" CREATED="1697807481495" ID="ID_1248086116" MODIFIED="1697807804662" TEXT="das hat sich durch die Implementierung etwas relativiert">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...wie so oft, vor allem getrieben durch die Tests: die Layer wurden zu einer Sammlung von Implementierungs-Bausteienen, welche auch aufeinander aufbauen. Aber die <i>große Verdrahtung </i>habe ich noch vor mir hergeschoben — sogar so weit, daß Layer-2 selbst keine Referenz auf Layer-1 besitzt (sondern diese für jede Funktion hereingereicht bekommt). Damit wird die Verdrahtung nun sternförmig, und der Binde-Code ist das, was den »Scheduler-Service« ausmacht
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="licq"/>
|
||||
</node>
|
||||
<node CREATED="1697807495135" ID="ID_1789450412" MODIFIED="1697807816218" TEXT="Thema »Binding und Zusammenarbeit« ist nun Sache des Scheduler-Service">
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node COLOR="#525b6f" CREATED="1697807963209" ID="ID_301601079" MODIFIED="1697808004356" TEXT="und: WorkForce selber wird vom Scheduler betrieben und ist eng verdrahtet">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1694130760121" ID="ID_661270953" MODIFIED="1694130794493" TEXT="das Shutdown- und Destruktor-Verhalten ist aber ein Problem für sich">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
|
|
@ -84741,6 +84811,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1694016294919" ID="ID_240227471" MODIFIED="1694016354350" TEXT="konkrete Impl muß Grooming-Token freigeben (sonst Deadlock möglich)">
|
||||
<arrowlink COLOR="#88617a" DESTINATION="ID_688462252" ENDARROW="Default" ENDINCLINATION="118;-18;" ID="Arrow_ID_953966962" STARTARROW="None" STARTINCLINATION="-312;13;"/>
|
||||
<linktarget COLOR="#fe3a8d" DESTINATION="ID_240227471" ENDARROW="Default" ENDINCLINATION="1819;-50;" ID="Arrow_ID_1740525983" SOURCE="ID_1793076416" STARTARROW="None" STARTINCLINATION="221;16;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1694016398145" ID="ID_1137833465" MODIFIED="1694016416375" TEXT="darüber können auch fatale Fehler kommuniziert werden">
|
||||
|
|
@ -84819,10 +84890,11 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
C++ zwingt uns dazu, explizit das zu tun was ohnehin getan werden muß; da jedoch der <i>Typ </i>der Config per Template-Parameter gewählt wird, ist komplettes Inlining möglich; letztlich wird daher nur ein Pointer auf das Scheduler-Objekt in alle Threads kopiert — <i>exakt das</i>  was wir brauchen
|
||||
C++ zwingt uns dazu, explizit das zu tun was ohnehin getan werden muß; da jedoch der <i>Typ </i>der Config per Template-Parameter gewählt wird, ist komplettes Inlining möglich; letztlich wird daher nur ein Pointer auf das Scheduler-Objekt in alle Threads kopiert — <i>exakt das</i> was wir brauchen
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<linktarget COLOR="#f3fea4" DESTINATION="ID_983915877" ENDARROW="Default" ENDINCLINATION="1743;-58;" ID="Arrow_ID_529465664" SOURCE="ID_1541537637" STARTARROW="None" STARTINCLINATION="822;78;"/>
|
||||
<icon BUILTIN="ksmiletris"/>
|
||||
</node>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue