Scheduler: implement and document capacity redirection
This commit is contained in:
parent
1d5b8c3e9c
commit
d6c859fd3a
5 changed files with 202 additions and 36 deletions
|
|
@ -42,8 +42,9 @@
|
|||
** the next task, an assessment of the timing situation is conducted, and the
|
||||
** worker is placed into some partition of the overall available capacity,
|
||||
** to reflect the current load and demand. Workers are thus moved between
|
||||
** the segments, preferring to assign work to workers already in the active
|
||||
** segment, thereby allowing idle workers to be shut down after some time.
|
||||
** the segments of capacity, preferring to assign work to workers already
|
||||
** in the active segment, thereby allowing idle workers to be shut down
|
||||
** after some time.
|
||||
**
|
||||
** The key element to decide upon the classification of a worker is the current
|
||||
** scheduling situation: are some Activities overdue? does the next Activity
|
||||
|
|
@ -52,7 +53,7 @@
|
|||
** to be in excess for now. A worker not required right now can be sent into a
|
||||
** targeted sleep delay, in order to shift its capacity into a zone where it
|
||||
** will more likely be required. It is essential to apply some randomisation
|
||||
** on such capacity shifts, in order to achieve an even distribution of free
|
||||
** on these capacity shifts, in order to achieve an even distribution of free
|
||||
** capacity and avoid contention between workers asking for new assignments.
|
||||
**
|
||||
** When a worker becomes available and is not needed at the moment, the first
|
||||
|
|
|
|||
|
|
@ -183,15 +183,8 @@ namespace gear {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* send this thread into a targeted short-time wait.
|
||||
* @return how to proceed further with this worker
|
||||
*/
|
||||
activity::Proc
|
||||
scatteredDelay (LoadController::Capacity capacity)
|
||||
{
|
||||
UNIMPLEMENTED("scattered short-term delay");
|
||||
}
|
||||
/** send this thread into a targeted short-time wait. */
|
||||
activity::Proc scatteredDelay (Time now, LoadController::Capacity);
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -202,7 +195,9 @@ namespace gear {
|
|||
{
|
||||
activity::Proc lastResult = activity::PASS;
|
||||
|
||||
/*** exposes the latest verdict as overall result */
|
||||
/** exposes the latest verdict as overall result
|
||||
* @note returning activity::SKIP from the dispatch
|
||||
* signals early exit, which is acquitted here. */
|
||||
operator activity::Proc()
|
||||
{
|
||||
return activity::SKIP == lastResult? activity::PASS
|
||||
|
|
@ -303,7 +298,7 @@ namespace gear {
|
|||
* @remarks this function is invoked from within the worker thread(s) and will
|
||||
* - decide if and how the capacity of this worker shall be used right now
|
||||
* - possibly go into a short targeted wait state to redirect capacity at a better time point
|
||||
* - and most notably jump into the dispatch of the render Activities, to calculate media data.
|
||||
* - and most notably commence with dispatch of render Activities, to calculate media data.
|
||||
* @return an instruction for the work::Worker how to proceed next:
|
||||
* - activity::PROC causes the worker to poll again immediately
|
||||
* - activity::SLEEP induces a sleep state
|
||||
|
|
@ -317,19 +312,47 @@ namespace gear {
|
|||
Time head = layer1_.headTime();
|
||||
|
||||
return WorkerInstruction{}
|
||||
.performStep([&]{ return scatteredDelay(
|
||||
.performStep([&]{ return scatteredDelay(now,
|
||||
loadControl_.markIncomingCapacity (head,now));
|
||||
})
|
||||
.performStep([&]{
|
||||
Activity* act = layer2_.findWork (layer1_,now);
|
||||
return ctx.post (now, act, ctx);
|
||||
})
|
||||
.performStep([&]{ return scatteredDelay(
|
||||
.performStep([&]{ return scatteredDelay(now,
|
||||
loadControl_.markOutgoingCapacity (head,now));
|
||||
})
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A worker [asking for work](\ref #getWork) constitutes free capacity,
|
||||
* which can be redirected into a focused zone of the scheduler time axis
|
||||
* where it is most likely to be useful, unless there is active work to
|
||||
* be carried out right away.
|
||||
* @param capacity classification of the capacity to employ this thread
|
||||
* @return how to proceed further with this worker
|
||||
* @note as part of the regular work processing, this function may
|
||||
* place the current thread into a short-term targeted sleep.
|
||||
*/
|
||||
inline activity::Proc
|
||||
Scheduler::scatteredDelay (Time now, LoadController::Capacity capacity)
|
||||
{
|
||||
switch (capacity) {
|
||||
case LoadController::DISPATCH:
|
||||
return activity::PASS;
|
||||
case LoadController::SPINTIME:
|
||||
std::this_thread::yield();
|
||||
return activity::PASS;
|
||||
case LoadController::IDLETIME:
|
||||
return activity::WAIT;
|
||||
default:
|
||||
Offset targetedDelay = loadControl_.scatteredDelayTime (now, capacity);
|
||||
std::this_thread::sleep_for (std::chrono::microseconds (_raw(targetedDelay)));
|
||||
return activity::PASS;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -281,7 +281,7 @@ namespace test {
|
|||
|
||||
auto expect = _raw(SLEEP_HORIZON)/2;
|
||||
auto error = fabs(avg/expect - 1);
|
||||
CHECK (0.001 > error); // observing a quite stable skew ~ 0.4‰ on my system
|
||||
CHECK (0.002 > error); // observing a quite stable skew ~ 0.8‰ on my system
|
||||
} // let's see if this error bound triggers eventually...
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -7201,19 +7201,39 @@ The Scheduler is now considered an implementation-level facility with an interfa
|
|||
→ [[Workers|SchedulerWorker]]
|
||||
</pre>
|
||||
</div>
|
||||
<div title="SchedulerLoadControl" creator="Ichthyostega" modifier="Ichthyostega" created="202310240240" modified="202310240251" tags="Rendering spec operational draft" changecount="3">
|
||||
<div title="SchedulerLoadControl" creator="Ichthyostega" modifier="Ichthyostega" created="202310240240" modified="202310241743" tags="Rendering operational spec draft" changecount="34">
|
||||
<pre>The scheduling mechanism //requires active control of work parameters to achieve good performance on average.//
|
||||
In a nutshell, the scheduler arranges planned [[render activities|RenderActivity]] onto a time axis -- and is complemented by an [[active »work force«|SchedulerWorker]] to //pull and retrieve// the most urgent next task when free processing capacity becomes available. This arrangement shifts focus from the //management of tasks// towards the //management of capacity// -- which seems more adequate, given that capacity is scarce while tasks are abundant, yet limited in size small and atomic.
|
||||
In a nutshell, the scheduler arranges planned [[render activities|RenderActivity]] onto a time axis -- and is complemented by an [[active »work force«|SchedulerWorker]] to //pull and retrieve// the most urgent next task when free processing capacity becomes available. This arrangement shifts focus from the //management of tasks// towards the //management of capacity// -- which seems more adequate, given that capacity is scarce while tasks are abundant, yet limited in size and processed atomically.
|
||||
|
||||
This change of perspective however implies that not the time-axis is in control; rather processing is driven by the workers, which happen to show up in a pattern assumed to be //essentially random.// This leads to the conclusion that capacity may not be available at the point where it's needed most, and some overarching yet slowly adapting scheme of redistribution is required to make the render engine run smoothly.
|
||||
|
||||
!Maintaining work capacity
|
||||
Capacity as such is an abstracted and statistical entity, emerging from the random pattern of worker pulls. The workers themselves can be in a subdued //sleeping state// -- causing the underlying OS thread to be sent into a time bound sleeping wait state, thereby freeing up the used computation »core« for other unrelated work. This kind of state transition involves a context switch to the OS kernel, which obviously bears some overhead to be minimised. ''Contemporary OS scheduling'' does not //rely on a fixed time slice model any more.// The kernel provides a high-resolution time source and employs an elaborate wake-up scheme, balancing the ability for //soft-realtime operation// with the imperative to //limit energy consumption// of the system. The software control-flow within an individual thread can thus make no reliable assumptions regarding uninterrupted processing, since pre-emption may happen anywhere, any time, irregularly and spanning a wide array of frequencies. When instructed for wake-up after a given time period, the actual response time can be much larger, yet //on average// a given wake-up goal is met with latencies ranging down into the low µs range. However, the actual response provided by the OS scheduler largely depends on the current load situation, and how this load is distributed over the available »cores«. A power management governance may prefer to concentrate all load on a small number of cores to allow stepping down excess computation resources. The consequence is: whenever several tasks are competing for active use of a core, the work time will be divided in accordance to demand -- striving to achieve the desired balance in the realm of 1...10 milliseconds. Effectively, not anything can taken for granted below 10 milliseconds.
|
||||
|
||||
This has ramifications for the Render Engine scheduling strategy.<br/>The goals are set as follows:
|
||||
* achieve optimal use of resources on average
|
||||
* adapt to a wide array of given circumstances
|
||||
Notably the use of special purpose hardware or special OS privileges is //not required,// yet the system should be able to exploit such abilities, when available. Taking into account the nature of contemporary OS scheduling, as outlined above, the ''fundamental strategy'' is constantly to produce //maximum demand for computation// on precisely that amount of concurrent threads //matching the number// of »cores« allocated to rendering. By default, the number indicated as {{{std::thread::hardware_concurrency()}}} by the C++ runtime system will be used, not more. Assuming that all other threads and processes are mostly sleeping on wait for events, producing such a load pattern will coerce the OS scheduler to allocate each of these demand-drawing worker threads to a single »core« and thereby granting the majority of available computation capacity to this single worker on each »core«.
|
||||
|
||||
This fundamental strategy translates into the goal to provide each worker with the next piece of work as soon as the thread returns from previous work. Putting this scheme into practice however faces major obstacles stemming from //work granularity// and //timing patterns.// Threads will call for work at essentially random time points, and in no way related to the calculation schedule laid out in advance based on reasoning about dependencies, resource allocation and deadlines. This is a problem hard to overcome on the level of individual operationality. And thus, in accordance to the goals set out above, demanding to aim at optimal use of recurses //on average// -- it is indicated to change to a //statistical perspective// and to interpret the worker call as an //capacity event.//
|
||||
!!!The statistical flow of capacity
|
||||
By employing this changed perspective, the ongoing train of worker calls transliterates into a flow of capacity. And this capacity can be grouped and classified. The optimal situation -- which should be achieved on average -- is to be able to provide the next piece of work //immediately// for each worker calling in. On the other hand, target times set out for scheduling should be observed, and thus this optimum state can be characterised as »being slightly overdue«. Ideally, capacity should thus flow-in //slightly behind schedule.// On an operational level, since „capacity flow“ is something generated stochastically, the desired state translates into adjustments to re-distribute the worker callback time points into some focal time zone, located slightly behind the next known [[render activity|RenderActivity]] to tend for. (As aside, an //alternative approach// -- likewise considered for the scheduler design -- would be to pre-attribute known capacity to the next round of known scheduling events; this solution was rejected however, presumably leading to excessively fine-grained and unnecessarily costly computation, disregarding the overall probabilistic nature of the rendering process.)
|
||||
|
||||
Drawing upon these principles, the treatment of worker calls can be aligned to the upcoming schedule. On average, the planning of this schedule can be assumed to happen in advance with suitably safety margin (notwithstanding the fact that re-scheduling and obliteration of established schedule can happen any time, especially in response to user interaction). The next-known »head element« of the schedule will thus play a //pivotal role,// when placed into the context of the //current time of request.// On average, this head element will be the next activity to consider, and the distance-of-encounter can be taken as indicator for //current density of work.// This allows to establish a priority of concerns to consider when answering a worker pull call, thereby transitioning the capacity-at-hand into a delineated segment of the overall capacity:
|
||||
# ideally, activities slightly overdue can be satisfied by //active capacity//
|
||||
# spinning-wait is adequate for imminent events below scheduling latency
|
||||
# next priority to consider is a head element located more into the future
|
||||
# beyond that, capacity can be redirected into a focussed zone behind the head
|
||||
# and if the head is far away, capacity is transitioned into the reserve segment
|
||||
Worker capacity events can be further distinguished into //incoming capacity// and //outgoing capacity.// The latter is the most desirable transition, since it corresponds to a worker just returning from a computation task, while incoming capacity stems from workers calling back after a sleep period. Thus a high priority is placed on re-assigning the outgoing capacity immediately back to further active work, while for incoming capacity there is an increased preference to send it back to sleep. A worker placed into the sleeping reserve for an extended stretch of time can be considered excess capacity and will be removed from the [[work force|SchedulerWorker]]. This kind of asymmetry creates a cascading flow, and allows in the end to synthesise an average load factor, which in turn can be used to regulate the Engine on a global level. If scheduling is overloaded, increasing the slip of planned timings, more capacity might be added back when available, or the planning process should be throttled accordingly.
|
||||
</pre>
|
||||
</div>
|
||||
<div title="SchedulerMemory" creator="Ichthyostega" modifier="Ichthyostega" created="202307031622" modified="202307220323" tags="Rendering operational draft" changecount="29">
|
||||
<div title="SchedulerMemory" creator="Ichthyostega" modifier="Ichthyostega" created="202307031622" modified="202310241427" tags="Rendering operational draft" changecount="31">
|
||||
<pre>//The Scheduler uses an »Extent« based memory management scheme known as {{{BlockFlow}}}.//
|
||||
The organisation of rendering happens in terms of [[Activities|RenderActivity]], which may bound by //dependencies// and limited by //deadlines.// For the operational point of view this implies that a sequence of allocations must be able to „flow through the Scheduler“ -- in fact, only references to these {{{Activity}}}-records are passed, while the actual descriptors reside at fixed memory locations. This is essential to model the dependencies and conditional execution structures efficiently. At some point however, any {{{Activity}}}-record will either be //performed// or //obsoleted// -- and this leads to the idea of managing the allocations in //extents// of memory here termed as »Epochs«
|
||||
* a new Activity is planted into a suitable //Epoch,// based on its deadline
|
||||
* it is guaranteed to sit at a fixed memory location while it can be activated potentially
|
||||
* based on the deadlines, at some point a complete strike of activities can be reasoned to be //obsoleted.//
|
||||
* it is guaranteed to sit at a fixed memory location while it can be potentially activated
|
||||
* based on the deadlines, at some point a complete slate of activities can reasonably be considered as //obsoleted.//
|
||||
* this allows to discard a complete Extent //without any further checks and processing// (assuming trivial destructors!)
|
||||
|
||||
!Safeguards
|
||||
|
|
@ -7255,7 +7275,7 @@ The primary scaling effects exploited to achieve this level of performance are t
|
|||
The way other parts of the system are built, requires us to obtain a guaranteed knowledge of some job's termination. It is possible to obtain that knowledge with some limited delay, but it nees to be absoultely reliable (violations leading to segfault). The requirements stated above assume this can be achieved through //jobs with guaranteed execution.// Alternatively we could consider installing specific callbacks -- in this case the scheduler itself has to guarantee the invocation of these callbacks, even if the corresponding job fails or is never invoked. It doesn't seem there is any other option.
|
||||
</pre>
|
||||
</div>
|
||||
<div title="SchedulerWorker" creator="Ichthyostega" modifier="Ichthyostega" created="202309041605" modified="202309101338" tags="Rendering spec draft" changecount="11">
|
||||
<div title="SchedulerWorker" creator="Ichthyostega" modifier="Ichthyostega" created="202309041605" modified="202310241448" tags="Rendering operational spec draft" changecount="13">
|
||||
<pre>The Scheduler //maintains a ''Work Force'' (a pool of workers) to perform the next [[render activities|RenderActivity]] continuously.//
|
||||
Each worker runs in a dedicated thread; the Activities are arranged in a way to avoid blocking those worker threads
|
||||
* IO operations are performed asynchronously {{red{planned as of 9/23}}}
|
||||
|
|
@ -7274,7 +7294,7 @@ The behaviour of individual workers is guided solely by the return-value flag fr
|
|||
* likewise, an exception from anywhere within the worker shall terminate the worker and activate a »disaster mode«
|
||||
Essentially this implies that //the workers themselves// (not some steering master) perform the management code leading to the aforementioned state directing return codes.
|
||||
|
||||
The ''idle-wait cycle'' involves some degree of capacity control. First off, a worker receiving the {{{activity::WAIT}}} should perform a sleep (by the OS scheduler) for some small period (configurable as Render Engine parameter). However, if a worker encounters an extended ongoing sequence of idle-wait cycles, beyond a (likewise configurable) threshold, the //worker shall terminate.// This way, the {{{WorkForce}}} gradually scales down when not used any more. On the other hand, //scaling up// is performed stepwise or in one jump, and triggered by an external control call, typically issued by the {{{Scheduler}}} in response to a signal from the {{{Player}}} indicating a newly added workload.
|
||||
The ''idle-wait cycle'' involves some degree of capacity control. First off, a worker receiving the {{{activity::WAIT}}} should perform a sleep (by the OS scheduler) for some small period (configurable as Render Engine parameter). However, if a worker encounters an extended ongoing sequence of idle-wait cycles, beyond a (likewise configurable) threshold, the //worker shall terminate.// This way, the {{{WorkForce}}} gradually scales down when not used any more. On the other hand, //scaling up// is performed stepwise or in one jump, and initiated by an [[external control call|SchedulerLoadControl]], typically conducted by the {{{Scheduler}}} in response to a signal from the {{{Player}}} indicating a newly added workload.
|
||||
|
||||
!!!Synchronisation and data consistency
|
||||
As pointed out above, the code controlling the worker behaviour must care for data consistency when using shared state. However, in the actual usage scenario for scheduling media computations the amount of »management work« is by orders of magnitude smaller than any actual media computations. For that reason, //all management work// involving shared data structures can be performed //exclusively single-threaded.// This is achieved by acquiring the {{{GroomingToken}}} within the Scheduler control layer (Layer-2). After mutating the queues to determine the next task, this token will be dropped again, prior to engaging into the actual media computations.
|
||||
|
|
|
|||
|
|
@ -82070,7 +82070,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
<node CREATED="1698004128887" ID="ID_933518899" MODIFIED="1698004135501" TEXT="outgoingCapacity"/>
|
||||
</node>
|
||||
<node CREATED="1698006786524" ID="ID_1037494295" MODIFIED="1698009675035" TEXT="monadische Kontrollstruktur">
|
||||
<node COLOR="#338800" CREATED="1698006786524" ID="ID_1037494295" MODIFIED="1698159351443" TEXT="monadische Kontrollstruktur">
|
||||
<icon BUILTIN="idea"/>
|
||||
<node CREATED="1698006794562" ID="ID_1254874787" MODIFIED="1698006827275" TEXT="sonst verdeckt die Behandlung des Control-flow die Entscheidungs-Logik">
|
||||
<icon BUILTIN="yes"/>
|
||||
|
|
@ -82084,6 +82084,15 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1698159488648" ID="ID_1616253878" MODIFIED="1698159495487" TEXT="Entscheidungs-Logik realisieren">
|
||||
<node CREATED="1698159497515" ID="ID_1173108252" MODIFIED="1698159508856" TEXT="geschieht weitgehend durch Zusammenfügen">
|
||||
<font ITALIC="true" NAME="SansSerif" SIZE="12"/>
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1698159517071" ID="ID_1595260615" MODIFIED="1698159535310" TEXT="Umsetzen der Kapazitäts-Entscheidung für Worker">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1698004014170" ID="ID_359097355" MODIFIED="1698004015766" TEXT="Test"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1697808056565" ID="ID_10043675" MODIFIED="1697808062704" TEXT="Fehlerbehandlung bedenken">
|
||||
|
|
@ -82272,8 +82281,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1698083418163" ID="ID_859036076" MODIFIED="1698083432553" TEXT="Lösung: Hilfsklasse mit Funktoren">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1698083418163" ID="ID_859036076" MODIFIED="1698185609731" TEXT="Lösung: Hilfsklasse mit Funktoren">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1698090000881" ID="ID_713507066" MODIFIED="1698090231201">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head/>
|
||||
|
|
@ -82717,7 +82726,7 @@ 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 COLOR="#338800" CREATED="1697983546449" ID="ID_1801117774" MODIFIED="1698110860930" TEXT="scatteredDelayTime()">
|
||||
<node COLOR="#338800" CREATED="1697983546449" FOLDED="true" ID="ID_1801117774" MODIFIED="1698110860930" TEXT="scatteredDelayTime()">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1698093070813" ID="ID_940807400" MODIFIED="1698110872107" TEXT="Parameter">
|
||||
<icon BUILTIN="info"/>
|
||||
|
|
@ -82919,6 +82928,9 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1698159441179" ID="ID_486995126" MODIFIED="1698159446891" TEXT="Scheduler-Tick">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1697982436029" ID="ID_288711039" MODIFIED="1698073045501" TEXT="Test">
|
||||
|
|
@ -97674,12 +97686,12 @@ class Something
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1664630921300" FOLDED="true" HGAP="183" ID="ID_1033335255" MODIFIED="1681004514646" TEXT="Dokumentation" VSHIFT="40">
|
||||
<node CREATED="1664630921300" FOLDED="true" HGAP="183" ID="ID_1033335255" MODIFIED="1698184443300" TEXT="Dokumentation" VSHIFT="40">
|
||||
<edge COLOR="#815b70"/>
|
||||
<cloud COLOR="#d7c3a8"/>
|
||||
<font NAME="SansSerif" SIZE="12"/>
|
||||
<icon BUILTIN="list"/>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1664630997672" FOLDED="true" ID="ID_237099051" MODIFIED="1681004517180" STYLE="bubble" TEXT="mitführen">
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1664630997672" FOLDED="true" ID="ID_237099051" MODIFIED="1698184439278" STYLE="bubble" TEXT="mitführen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
|
|
@ -97690,9 +97702,16 @@ class Something
|
|||
</html></richcontent>
|
||||
<icon BUILTIN="back"/>
|
||||
<node CREATED="1664631055889" ID="ID_1519064192" MODIFIED="1664631546287" STYLE="fork" TEXT="TiddlyWiki">
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1664631069343" ID="ID_905113359" LINK="file:///Lager/heim/devel/lumi/wiki/renderengine.html#GuiTopLevel%20GuiTimelineView%20TimelineDisplayManager%20TrackPresenter%20ClipPresenter%20GuiTimelineDraw%20GuiClipWidget%20GuiElementBoxWidget" MODIFIED="1664631546287" TEXT="Themenkomplex: GuiConnection">
|
||||
<node COLOR="#338800" CREATED="1664631069343" ID="ID_905113359" LINK="file:///Lager/heim/devel/lumi/wiki/renderengine.html#GuiTopLevel%20GuiTimelineView%20TimelineDisplayManager%20TrackPresenter%20ClipPresenter%20GuiTimelineDraw%20GuiClipWidget%20GuiElementBoxWidget" MODIFIED="1680371742398" TEXT="Themenkomplex: GuiConnection">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#19166e" CREATED="1611035931543" HGAP="54" ID="ID_936662203" MODIFIED="1698170758923" STYLE="bubble" TEXT="2023-3 abgeschlossen" VSHIFT="-4">
|
||||
<edge COLOR="#3596a7" STYLE="sharp_linear" WIDTH="2"/>
|
||||
<font ITALIC="true" NAME="SansSerif" SIZE="11"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1698169966766" ID="ID_285781159" LINK="file:///Lager/heim/devel/lumi/wiki/renderengine.html#PlaybackVerticalSlice%20RenderEngine%20Scheduler%20SchedulerWorker%20SchedulerMemory%20RenderActivity%20Player%20FrameDispatcher%20JobPlanningPipeline%20PlayProcess%20Rendering%20ProcNode%20NodeOperationProtocol" MODIFIED="1698170020932" TEXT="Themenkomples: Render-Engine">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#5b166e" CREATED="1611035931543" HGAP="77" ID="ID_936662203" MODIFIED="1664631233866" STYLE="bubble" TEXT="2022-10 aktiv" VSHIFT="-3">
|
||||
<node COLOR="#5b166e" CREATED="1611035555555" HGAP="81" ID="ID_152517956" MODIFIED="1611035586584" STYLE="bubble" TEXT="2023-10 aktiv" VSHIFT="28">
|
||||
<edge COLOR="#eb1854" STYLE="sharp_linear" WIDTH="2"/>
|
||||
<font ITALIC="true" NAME="SansSerif" SIZE="11"/>
|
||||
</node>
|
||||
|
|
@ -97712,9 +97731,59 @@ class Something
|
|||
<node CREATED="1664631363943" ID="ID_879637950" MODIFIED="1664631546287" STYLE="fork" TEXT="Doxygen">
|
||||
<node CREATED="1664631381728" ID="ID_479695439" MODIFIED="1664631546287" TEXT="Übersichten"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1698171927842" FOLDED="true" HGAP="31" ID="ID_198610920" MODIFIED="1698184363431" TEXT="Design-Process" VSHIFT="6">
|
||||
<edge COLOR="#605376"/>
|
||||
<icon BUILTIN="hourglass"/>
|
||||
<node CREATED="1698171979378" ID="ID_796194362" MODIFIED="1698172058077" STYLE="fork" TEXT="Stand">
|
||||
<icon BUILTIN="info"/>
|
||||
<node BACKGROUND_COLOR="#ccb59b" COLOR="#6e2a38" CREATED="1698172064496" ID="ID_806570820" MODIFIED="1698172243263" TEXT="grundsätzlich gülig — aber nicht weitergeführt">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Ich betrachte den Inhalt der RfC grundsätzlich als gültig und bindend. Aber seitdem ich alleine am Projekt arbeite, ist dieses Format nicht mehr sinnvoll, denn ich diskutiere nun <i>pro forma</i> mit mir selber, dafür aber in einer viel größeren Tiefe
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<font ITALIC="true" NAME="SansSerif" SIZE="14"/>
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1698172250767" ID="ID_1281403924" MODIFIED="1698172264756" TEXT="einige Entscheidungen haben sich überholt">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1698171979378" ID="ID_48382170" MODIFIED="1698172023477" STYLE="fork" TEXT="Aufgaben">
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1698172278156" ID="ID_1995120982" MODIFIED="1698184355670" TEXT="obsolete und irreführende Entscheidungen widerrufen">
|
||||
<icon BUILTIN="bell"/>
|
||||
<node COLOR="#338800" CREATED="1698172333812" ID="ID_1019479183" MODIFIED="1698172336941" TEXT="Lua">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1698172352697" ID="ID_1644963280" MODIFIED="1698184315004" TEXT="C-Interfaces">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1698172345323" ID="ID_571636963" MODIFIED="1698184317754" TEXT="Data Backend">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1698172411954" ID="ID_1558596731" MODIFIED="1698172528830" TEXT="fragwürdige Entscheidungen kennzeichnen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1698172656660" ID="ID_1707252412" MODIFIED="1698172656660" TEXT="Distributed Development Framework"/>
|
||||
<node CREATED="1698173627465" ID="ID_510133323" MODIFIED="1698173636930" TEXT="Config System Draft"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1698172530866" ID="ID_1104963418" MODIFIED="1698172543633" TEXT="zusätzliche Kategorie: »obsolete«">
|
||||
<icon BUILTIN="flag-pink"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1698172315878" ID="ID_411928990" MODIFIED="1698172323414" TEXT="neue Organisationsstruktur überlegen">
|
||||
<icon BUILTIN="hourglass"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1698171979378" ID="ID_957531177" MODIFIED="1698172030504" STYLE="fork" TEXT="Diskussion"/>
|
||||
</node>
|
||||
<node CREATED="1664631398891" ID="ID_1010017470" MODIFIED="1664631559120" STYLE="fork" TEXT="LumiDok">
|
||||
<edge COLOR="#8e6074" STYLE="linear" WIDTH="thin"/>
|
||||
<node CREATED="1664631418128" ID="ID_1118945815" MODIFIED="1664631559116" TEXT="Stand">
|
||||
<node CREATED="1664631418128" HGAP="13" ID="ID_1118945815" MODIFIED="1698171900334" TEXT="Stand" VSHIFT="-4">
|
||||
<font NAME="SansSerif" SIZE="15"/>
|
||||
<icon BUILTIN="info"/>
|
||||
<node COLOR="#435e98" CREATED="1664632273717" ID="ID_546161915" MODIFIED="1681004578460" TEXT="10/22: master/online deutlich zurückgefallen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
|
|
@ -97782,9 +97851,62 @@ class Something
|
|||
</node>
|
||||
</node>
|
||||
<node CREATED="1664631424771" ID="ID_30685930" MODIFIED="1664631559117" TEXT="User"/>
|
||||
<node CREATED="1664631468424" ID="ID_206416201" MODIFIED="1664631559117" TEXT="Design"/>
|
||||
<node CREATED="1664631468424" ID="ID_206416201" MODIFIED="1664631559117" TEXT="Design">
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1698170208238" ID="ID_966155424" MODIFIED="1698170215726" TEXT="Engine">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1698170224708" ID="ID_484068209" MODIFIED="1698170248746" TEXT="das inzwischen entwickelte Design dokumentieren">
|
||||
<icon BUILTIN="bell"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1664631471329" ID="ID_1395212182" MODIFIED="1664631559117" TEXT="Technical">
|
||||
<node CREATED="1664631954289" ID="ID_20498937" MODIFIED="1664631956996" TEXT="GTK">
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1698170277259" FOLDED="true" ID="ID_800254076" MODIFIED="1698184383476" TEXT="Vault">
|
||||
<icon BUILTIN="bell"/>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1698170303291" ID="ID_1001821609" MODIFIED="1698170316232" TEXT="Scheduler">
|
||||
<icon BUILTIN="clanbomber"/>
|
||||
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1698170319519" ID="ID_1106925794" MODIFIED="1698170341404" TEXT="hier stehen noch uralte »implementation ideas«">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1698170383474" ID="ID_1329793697" MODIFIED="1698184325482" TEXT="wenigstens schon mal den neuen Fokus anzeigen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1698173836465" ID="ID_1042892141" MODIFIED="1698173844663" TEXT="Config Loader">
|
||||
<icon BUILTIN="stop-sign"/>
|
||||
<node CREATED="1698173846842" ID="ID_164165293" MODIFIED="1698173857352" TEXT="das ist ein »draft«"/>
|
||||
<node CREATED="1698173858072" ID="ID_9681986" MODIFIED="1698173867195" TEXT="er wurde nie weitergeführt"/>
|
||||
<node CREATED="1698173867807" ID="ID_205034475" MODIFIED="1698173874138" TEXT="ich möchte in eine andere Richtung gehen"/>
|
||||
<node COLOR="#338800" CREATED="1698173877046" ID="ID_111961244" MODIFIED="1698184333391" TEXT="Beschluß: in RfC umwandeln">
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1698170542481" ID="ID_417122450" MODIFIED="1698170545532" TEXT="Lowlevel">
|
||||
<node COLOR="#338800" CREATED="1698170546569" FOLDED="true" ID="ID_1509961741" MODIFIED="1698184426790" TEXT="überschüssig: Scheduler">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1698170565262" ID="ID_1059255666" MODIFIED="1698184395634" TEXT="da ist noch eine Seite angelegt">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
<node COLOR="#5b280f" CREATED="1698170598506" ID="ID_694594892" MODIFIED="1698170711735" TEXT="Scheduler als reiner Backend-Service">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Das ist eine Sichtweise auf die Architektur, die ich inzwischen überwunden habe
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="stop-sign"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1698184396962" ID="ID_188360452" MODIFIED="1698184421620" TEXT="Seite ersatzlos entfernt">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1698184414015" ID="ID_853555332" MODIFIED="1698184421199" TEXT="Backend-Text gekürzt">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1664631954289" HGAP="36" ID="ID_20498937" MODIFIED="1698170299487" TEXT="GTK" VSHIFT="1">
|
||||
<node CREATED="1664631960544" ID="ID_366289631" MODIFIED="1664631964860" TEXT="Layout"/>
|
||||
<node CREATED="1664631965465" ID="ID_417783849" LINK="http://localhost:8888/documentation/technical/stage/style/index.html" MODIFIED="1664658971571" TEXT="Styling">
|
||||
<linktarget COLOR="#684e97" DESTINATION="ID_417783849" ENDARROW="Default" ENDINCLINATION="-182;50;" ID="Arrow_ID_321858822" SOURCE="ID_782976986" STARTARROW="None" STARTINCLINATION="143;23;"/>
|
||||
|
|
|
|||
Loading…
Reference in a new issue