Block-Flow: detect and react on Epoch overflow

..using a simplistic implementation for now: scale down the
Epoch-stepping by 0.9 to increase capacity accordingly.
This is done on each separate overflow event, and will be
counterbalanced by the observation of Epoch fill ratio
performed later on clean-up of completed Epochs
This commit is contained in:
Fischlurch 2023-07-16 20:47:39 +02:00
parent 6d75a82932
commit bd353d768a
4 changed files with 179 additions and 99 deletions

View file

@ -28,7 +28,7 @@
** as messages through the scheduler, the actual implementation requires a fixed
** descriptor record sitting at a stable memory location while the computation
** is underway. Moreover, activities can spawn further activities, implying that
** activity descriptor records can emanate from multiple threads concurrently,
** activity descriptor records for various deadlines need to be accommodated
** and the duration to keep those descriptors in valid state is contingent.
** On the other hand, ongoing rendering produces a constant flow of further
** activities, necessitating timely clean-up of obsolete descriptors.
@ -36,6 +36,34 @@
** pooled allocation tiles, extending the underlying block
** allocation on increased throughput.
**
** # Implementation technique
**
** The usage within the [Scheduler](\ref scheduler.hpp) can be arranged in a way
** to avoid concurrency issues altogether; while allocations are not always done
** by _the same thread,_ it can be ensured at any given time that only a single
** Worker performs Scheduler administrative tasks (queue management and allocation);
** a read/write barrier is issued whenever some Worker enters this management mode.
**
** Memory is allocated in larger _extents,_ which are then used to place individual
** fixed-size allocations. These are not managed further, assuming that the storage
** is used for POD data records, and the destructors need not be invoked at all.
** This arrangement is achieved by interpreting the storage extents as temporal
** *Epochs*. Each #Epoch holds an Epoch::EpochGate to define a deadline and to allow
** blocking this Epoch by pending IO operations (with the help of a count-down latch).
** The rationale is based on the observation that any render activity for late and
** obsolete goals is pointless and can be just side stepped. Once the scheduling has
** passed a defined deadline (and no further pending IO operations are around), the
** Epoch can be abandoned as a whole and the storage extent can be re-used.
**
** Dynamic adjustments are necessary to keep this scheme running efficiently.
** Ideally, the temporal stepping between subsequent Epochs should be chosen such
** as to accommodate all render activities with deadlines falling into this Epoch,
** without wasting much space for unused storage slots. But the throughput and thus
** the allocation pressure of the scheduler can change intermittently, necessitating
** to handle excess allocations by shifting them into the next Epoch. These _overflow
** events_ are registered, and on clean-up the actual usage ratio of each Epoch is
** detected, leading to exponentially damped adjustments of the actual Epoch duration.
**
** @note currently this rather marks the intended memory management pattern,
** while the actual allocations are still performed on the heap.
** @see BlockFlow_test
@ -84,7 +112,7 @@ namespace gear {
const Duration INITIAL_EPOCH_STEP{FRAMES_PER_EPOCH * FrameRate{50}.duration()};
const Rat OVERFLOW_BOOST_FACTOR = 9_r/10; ///< increase capacity on each Epoch overflow event
const Rat OVERFLOW_BOOST_FACTOR = 9_r/10; ///< increase capacity on each Epoch overflow event
const size_t AVERAGE_EPOCHS = 10; ///< moving average len for exponential convergence towards average Epoch fill
/** raw allocator to provide a sequence of Extents to place Activity records */
@ -92,6 +120,7 @@ namespace gear {
}
/**
* Allocation Extent holding _scheduler Activities_ to be performed altogether
@ -187,7 +216,7 @@ namespace gear {
/**
/******************************************************//**
* Allocation scheme for the Scheduler, based on Epoch(s).
* Scheduling entails to provide a chain of Activity definitions,
* which will then »flow« through the priority queue until invocation.
@ -237,7 +266,7 @@ namespace gear {
}
/** Adapted storage-extent iterator, directly exposing Extent& */
/** Adapted storage-Extent iterator, directly exposing Epoch& */
using EpochIter = lib::IterableDecorator<Epoch, StorageAdaptor>;
@ -279,19 +308,29 @@ namespace gear {
void*
claimSlot() ///< EX_SANE
{
bool first{true};
while (not (epoch_ and
epoch_->gate().hasFreeSlot()))
// Epoch overflow
// use following Epoch; possibly allocate
if (not epoch_)
{
auto lastDeadline = flow_->lastEpoch().deadline();
epoch_.expandAlloc();
ENSURE (epoch_);
Epoch::setup (epoch_, lastDeadline + flow_->getEpochStep());
}
else
++epoch_;
{
if (first)
{// each shifted allocation accounted once as overflow
flow_->markEpochOverflow();
first = false;
}
if (not epoch_)
{
auto lastDeadline = flow_->lastEpoch().deadline();
epoch_.expandAlloc(); // may throw out-of-memory..
ENSURE (epoch_);
Epoch::setup (epoch_, lastDeadline + flow_->getEpochStep());
}
else
{
++epoch_;
}
}
return epoch_->gate().claimNextSlot();
}
};
@ -299,6 +338,10 @@ namespace gear {
/* ===== public BlockFlow API ===== */
/**
* initiate allocations for activities to happen until some deadline
* @return opaque handle allowing to perform several allocations.
*/
AllocatorHandle
until (Time deadline)
{
@ -323,7 +366,7 @@ namespace gear {
ENSURE (not nextEpoch); // not valid yet, but we will allocate starting there...
auto requiredNew = distance / _raw(epochStep_);
if (distance % _raw(epochStep_) > 0)
++requiredNew; // fractional: requested deadline lies within last epoch
++requiredNew; // fractional: requested deadline lies within last epoch
alloc_.openNew(requiredNew); // Note: epochHandle now points to the first new Epoch
for ( ; 0 < requiredNew; --requiredNew)
{
@ -348,6 +391,13 @@ namespace gear {
}
}
/**
* Clean-up all storage related to activities before the given deadline.
* @note when some Epoch is blocked by pending IO, all subsequent Epochs
* will be kept alive too, since the returning IO operation may trigger
* activities there (at least up to the point where the control logic
* detects a timeout and abandons the execution chain).
*/
void
discardBefore (Time deadline)
{
@ -376,7 +426,7 @@ namespace gear {
void
markEpochOverflow()
{
UNIMPLEMENTED ("adjust size after overflow");
adjustEpochStep (OVERFLOW_BOOST_FACTOR);
}
/**

View file

@ -66,7 +66,6 @@ namespace test {
run (Arg)
{
simpleUsage();
verifyAPI();
handleEpoch();
placeActivity();
adjustEpochs();
@ -96,19 +95,6 @@ namespace test {
/** @test verify the primary BlockFlow API functions in isolation
* @todo WIP 7/23 define implement
*/
void
verifyAPI()
{
//SHOW_EXPR(watch(bFlow).cntEpochs());
//SHOW_EXPR(watch(bFlow).poolSize());
//SHOW_EXPR(watch(bFlow).first());
}
/** @test cover properties and handling of Epochs (low-level)
* - demonstrate that Epoch is placed into an Extent
* - verify that both Extent and Epoch access the same memory block
@ -200,8 +186,16 @@ namespace test {
/** @test TODO place Activity record into storage
* @todo WIP 7/23 define 🔁implement
/** @test place Activity record into storage
* - new Activity without any previously established Epoch
* - place Activity into future, expanding the Epoch grid
* - locate Activity relative to established Epoch grid
* - fill up existing Epoch, causing overflow to next one
* - exhaust multiple adjacent Epochs, overflowing to first free one
* - exhaust last Epoch, causing setup of new Epoch, with reduced spacing
* - use this reduced spacing also for subsequently created Epochs
* - clean up obsoleted Epochs, based on given deadline
* @todo WIP 7/23 define implement
*/
void
placeActivity()
@ -212,24 +206,28 @@ namespace test {
Time t2 = Time{500,10};
Time t3 = Time{ 0,11};
// no Epoch established yet...
auto& a1 = bFlow.until(t1).create();
CHECK (watch(bFlow).allEpochs() == "10s200ms"_expect);
CHECK (watch(bFlow).find(a1) == "10s200ms"_expect);
// setup Epoch grid into the future
auto& a3 = bFlow.until(t3).create();
CHECK (watch(bFlow).allEpochs() == "10s200ms|10s400ms|10s600ms|10s800ms|11s"_expect);
CHECK (watch(bFlow).find(a3) == "11s"_expect);
// associate to existing Epoch
auto& a2 = bFlow.until(t2).create();
CHECK (watch(bFlow).allEpochs() == "10s200ms|10s400ms|10s600ms|10s800ms|11s"_expect);
CHECK (watch(bFlow).find(a2) == "10s600ms"_expect);
Time t0 = Time{0,5};
// late(past) Activity is placed in the oldest Epoch alive
auto& a0 = bFlow.until(t0).create();
CHECK (watch(bFlow).allEpochs() == "10s200ms|10s400ms|10s600ms|10s800ms|11s"_expect);
CHECK (watch(bFlow).find(a0) == "10s200ms"_expect);
// provoke Epoch overflow by exhausting all available storage slots
BlockFlow::AllocatorHandle allocHandle = bFlow.until(Time{300,10});
for (uint i=1; i<Epoch::SIZ(); ++i)
allocHandle.create();
@ -237,20 +235,25 @@ namespace test {
CHECK (allocHandle.currDeadline() == Time(400,10));
CHECK (not allocHandle.hasFreeSlot());
// ...causing next allocation to be shifted into subsequent Epoch
auto& a4 = allocHandle.create();
CHECK (allocHandle.currDeadline() == Time(600,10));
CHECK (allocHandle.hasFreeSlot());
CHECK (watch(bFlow).find(a4) == "10s600ms"_expect);
// fill up and exhaust this Epoch too....
for (uint i=1; i<Epoch::SIZ(); ++i)
allocHandle.create();
// so the handle has moved to the after next Epoch
CHECK (allocHandle.currDeadline() == Time(800,10));
CHECK (allocHandle.hasFreeSlot());
// even allocation with way earlier deadline is shifted here now
auto& a5 = bFlow.until(Time{220,10}).create();
CHECK (watch(bFlow).find(a5) == "10s800ms"_expect);
// now repeat the same pattern, but now towards uncharted Epochs
allocHandle = bFlow.until(Time{900,10});
for (uint i=2; i<Epoch::SIZ(); ++i)
allocHandle.create();
@ -258,24 +261,27 @@ namespace test {
CHECK (allocHandle.currDeadline() == Time(0,11));
CHECK (not allocHandle.hasFreeSlot());
auto& a6 = bFlow.until(Time{850,10}).create();
CHECK (watch(bFlow).find(a6) == "11s150ms"_expect);
CHECK (watch(bFlow).allEpochs() == "10s200ms|10s400ms|10s600ms|10s800ms|11sms|11s150ms"_expect);
// Note: encountered four overflow-Events, leading to decreased Epoch spacing for new Epochs
CHECK (watch(bFlow).find(a6) == "11s131ms"_expect);
CHECK (watch(bFlow).allEpochs() == "10s200ms|10s400ms|10s600ms|10s800ms|11s|11s131ms"_expect);
auto& a7 = bFlow.until(Time{500,11}).create();
CHECK (watch(bFlow).find(a7) == "11s600ms"_expect);
CHECK (watch(bFlow).allEpochs() == "10s200ms|10s400ms|10s600ms|10s800ms|11sms|11s150ms|11s300ms|11s450ms|11s600ms"_expect);
// this allocation does not count as overflow, but has to expand the Epoch grid, now using the reduced Epoch spacing
CHECK (watch(bFlow).allEpochs() == "10s200ms|10s400ms|10s600ms|10s800ms|11s|11s131ms|11s262ms|11s393ms|11s524ms"_expect);
CHECK (watch(bFlow).find(a7) == "11s524ms"_expect);
bFlow.discardBefore (Time{999,10});
CHECK (watch(bFlow).allEpochs() == "11s|11s150ms|11s300ms|11s450ms|11s600ms"_expect);
CHECK (watch(bFlow).allEpochs() == "11s|11s131ms|11s262ms|11s393ms|11s524ms"_expect);
// placed into the oldest Epoch still alive
auto& a8 = bFlow.until(Time{500,10}).create();
CHECK (watch(bFlow).find(a8) == "11s150ms"_expect);
CHECK (watch(bFlow).find(a8) == "11s131ms"_expect);
}
/** @test TODO load based regulation of Epoch spacing
* @todo WIP 7/23 🔁define implement
* @todo WIP 7/23 define 🔁implement
*/
void
adjustEpochs()
@ -307,7 +313,7 @@ namespace test {
/** @test TODO maintain progression of epochs.
* @todo WIP 7/23 define implement
* @todo WIP 7/23 🔁define implement
*/
void
storageFlow()

View file

@ -6183,7 +6183,7 @@ This is the core service provided by the player subsystem. The purpose is to cre
:any details of this processing remain opaque for the clients; even the player subsystem just accesses the EngineFaçade
</pre>
</div>
<div title="PlaybackVerticalSlice" creator="Ichthyostega" modifier="Ichthyostega" created="202303272236" modified="202307032218" tags="overview impl discuss draft" changecount="31">
<div title="PlaybackVerticalSlice" creator="Ichthyostega" modifier="Ichthyostega" created="202303272236" modified="202307161834" tags="overview impl discuss draft" changecount="33">
<pre>//Integration effort to promote the development of rendering, playback and video display in the GUI//
This IntegrationSlice was started in {{red{2023}}} as [[Ticket #1221|https://issues.lumiera.org/ticket/1221]] to coordinate the completion and integration of various implementation facilities, planned, drafted and built during the last years; this effort marks the return of development focus to the lower layers (after years of focussed UI development) and will implement the asynchronous and time-bound rendering coordinated by the [[Scheduler]] in the [[Vault|Vault-Layer]]
@ -6222,6 +6222,11 @@ The Scheduler will be structured into two Layers, where the lower layer is imple
:* thus needs to //understand Job dependencies//
:* will be decomposed into several implementation layers
:SchedulerMemory will be managed by an //Extent scheme.//
;Asynchronous IO
:is treated as a responsibility and may block dependent planned activities
:a dependency check is operationalised as activity primitive and also used to hold allocations alive
:operational control and data management is //performed by the workers// interspersed with render activities
:however, only one worker at any time is allowed to perform these meta tasks, avoiding further synchronisation
</pre>
</div>
<div title="Player" modifier="Ichthyostega" created="201012181700" modified="202304140114" tags="def overview" changecount="4">
@ -7095,7 +7100,7 @@ The Scheduler is now considered an implementation-level facility with an interfa
&amp;rarr; [[Workers|SchedulerWorker]]
</pre>
</div>
<div title="SchedulerMemory" creator="Ichthyostega" modifier="Ichthyostega" created="202307031622" modified="202307121942" tags="Rendering operational draft" changecount="20">
<div title="SchedulerMemory" creator="Ichthyostega" modifier="Ichthyostega" created="202307031622" modified="202307161840" tags="Rendering operational draft" changecount="21">
<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
@ -7110,7 +7115,7 @@ Unfortunately this tricky arrangement also implies that many safety barriers of
* each »Epoch« gets an associated //deadline//
* when the next [[job|RenderJob]] processed by a worker starts //after this Epoch's deadline//, the worker //has left the Epoch.//
* when all workers have left an Epoch, only ''pending async IO tasks'' need to be considered, since IO can possibly be delayed for an extended period of time.&lt;br/&gt;For an IO task, buffers //need to be kept available,// and those buffers are indirectly tied to the job depending on them.
* ⟹ thus a count of pending IO activities must be maintained //for each Epoch// -- implemented by the same mechanism also employed for dependencies between render jobs, which is a notification message causing a local counter to be decremented.
* ⟹ thus a count of pending IO activities must be maintained //for each Epoch// -- implemented by the same mechanism also employed for dependencies between render jobs, which is a notification message causing a local counter to be decremented.&lt;br/&gt;All Epochs ''following the blocked one must be blocked as well'' -- since the callback from IO may immediately pass control there; only later, when the execution logic detects a passed deadline, it is possible to side step further activities; this is achieved by inserting {{{GATE}}}-[[Activity records|RenderActivity]] before any render job invocation bound by deadline.
!operational capabilities
The memory management for the scheduler is arranged into three layers...

View file

@ -78830,8 +78830,8 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node CREATED="1688336974018" ID="ID_1806920884" MODIFIED="1688337018608" TEXT="&#xbb;Epoch&#xab; based memory layout">
<icon BUILTIN="info"/>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1688562176925" ID="ID_1158793893" MODIFIED="1688562236828" TEXT="simpleUsage">
<icon BUILTIN="pencil"/>
<node COLOR="#338800" CREATED="1688562176925" ID="ID_1158793893" MODIFIED="1689529124622" TEXT="simpleUsage">
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1688562183720" ID="ID_112254409" MODIFIED="1688562193713" TEXT="BlockFlow erzeugen">
<icon BUILTIN="button_ok"/>
</node>
@ -78841,21 +78841,20 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node COLOR="#338800" CREATED="1688562204824" ID="ID_101196546" MODIFIED="1689215743991" TEXT="Diagnose: Allokation erfolgte">
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1688562219790" ID="ID_1157838911" LINK="#ID_455793213" MODIFIED="1689246472425" TEXT="aufr&#xe4;umen">
<icon BUILTIN="bell"/>
<node COLOR="#338800" CREATED="1688562219790" ID="ID_1157838911" LINK="#ID_455793213" MODIFIED="1689529126409" TEXT="aufr&#xe4;umen">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1688562225717" ID="ID_1423239902" MODIFIED="1689215748484" TEXT="Diagnose: Allocation wech">
<icon BUILTIN="button_ok"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1688514837919" ID="ID_23367137" MODIFIED="1688514850742" TEXT="API-Operationen">
<icon BUILTIN="flag-yellow"/>
<node CREATED="1688514860052" ID="ID_1887728481" MODIFIED="1688514863244" TEXT="Action allozieren"/>
<node CREATED="1688514904095" ID="ID_819616913" MODIFIED="1688514909523" TEXT="sp&#xe4;teste Deadline"/>
<node CREATED="1688514944443" ID="ID_341749929" MODIFIED="1688514974588" TEXT="Aufr&#xe4;umen vor Zeit"/>
<node COLOR="#338800" CREATED="1688514837919" ID="ID_23367137" MODIFIED="1689529122514" TEXT="API-Operationen">
<icon BUILTIN="button_ok"/>
<node COLOR="#435e98" CREATED="1688514860052" ID="ID_1887728481" MODIFIED="1689529113503" TEXT="Action allozieren"/>
<node COLOR="#435e98" CREATED="1688514944443" ID="ID_341749929" MODIFIED="1689529119926" TEXT="Aufr&#xe4;umen vor Zeit"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1688515088451" ID="ID_254117288" MODIFIED="1688515092923" TEXT="Epochen-Operationen">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1688515088451" ID="ID_254117288" MODIFIED="1689529134587" TEXT="Epochen-Operationen">
<icon BUILTIN="button_ok"/>
<node CREATED="1688515094346" ID="ID_1027706144" MODIFIED="1688515110180" TEXT="Epoche finden oder erstellen"/>
<node CREATED="1688515126831" ID="ID_1528998679" MODIFIED="1688515184828" TEXT="Epoche aktiv oder obsolet"/>
<node CREATED="1689199348011" ID="ID_946314952" MODIFIED="1689199354365" TEXT="F&#xfc;llstand der Epoche"/>
@ -78867,8 +78866,8 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1689199958807" ID="ID_1109817733" MODIFIED="1689199964871" TEXT="verifyAPI">
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1689199390484" ID="ID_679990341" MODIFIED="1689294955243" TEXT="handleEpoch">
<icon BUILTIN="pencil"/>
<node COLOR="#338800" CREATED="1689199390484" ID="ID_679990341" MODIFIED="1689529143322" TEXT="handleEpoch">
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1689202254231" ID="ID_322073846" MODIFIED="1689294940657" TEXT="Eigenschaften einer neu erstellten Epoche">
<icon BUILTIN="button_ok"/>
</node>
@ -78885,8 +78884,8 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<icon BUILTIN="button_ok"/>
</node>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1689199616791" ID="ID_752152349" MODIFIED="1689303038986" TEXT="placeActivity">
<icon BUILTIN="pencil"/>
<node COLOR="#338800" CREATED="1689199616791" ID="ID_752152349" MODIFIED="1689529149220" TEXT="placeActivity">
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1689202512708" ID="ID_101278669" MODIFIED="1689449425443" TEXT="in leeren BlockFlow">
<icon BUILTIN="button_ok"/>
</node>
@ -78902,20 +78901,20 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node COLOR="#338800" CREATED="1689202576227" ID="ID_1382030737" MODIFIED="1689449434375" TEXT="in die Zukunft">
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1689202597977" ID="ID_1853102157" MODIFIED="1689303033030" TEXT="Overflow zu n&#xe4;chster Epoche">
<node COLOR="#338800" CREATED="1689202597977" ID="ID_1853102157" MODIFIED="1689529147060" TEXT="Overflow zu n&#xe4;chster Epoche">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1689202609159" ID="ID_985814955" MODIFIED="1689529148297" TEXT="Overflow zuk&#xfc;nftige Epoche">
<icon BUILTIN="button_ok"/>
</node>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1689203745600" ID="ID_838958031" MODIFIED="1689529156713" TEXT="adjustEpochs">
<icon BUILTIN="pencil"/>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1689202609159" ID="ID_985814955" MODIFIED="1689303033030" TEXT="Overflow zuk&#xfc;nftige Epoche">
<icon BUILTIN="pencil"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1689203745600" ID="ID_838958031" MODIFIED="1689203950019" TEXT="adjustEpochs">
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1689203960637" ID="ID_1138375951" MODIFIED="1689203988840" TEXT="time averaging mechanism">
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1689203990663" ID="ID_1418143690" MODIFIED="1689204013293" TEXT="Overflow reduziert Spacing">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1689203990663" ID="ID_1418143690" MODIFIED="1689529153771" TEXT="Overflow reduziert Spacing">
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1689204050903" ID="ID_1034064454" MODIFIED="1689204057137" TEXT="Freigabe bewertet F&#xfc;llstand">
<icon BUILTIN="flag-yellow"/>
@ -79331,6 +79330,12 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<linktarget COLOR="#537a8e" DESTINATION="ID_253828146" ENDARROW="Default" ENDINCLINATION="399;21;" ID="Arrow_ID_1328212863" SOURCE="ID_900655074" STARTARROW="None" STARTINCLINATION="508;-25;"/>
</node>
</node>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1689531790724" ID="ID_1704448031" MODIFIED="1689531819648" TEXT="Achtung: nachfolgende Epochen m&#xfc;ssen dann ebenfalls geblockt bleiben">
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1689531829719" ID="ID_1345957501" MODIFIED="1689531834674" TEXT="t&#xfc;ckische Falle"/>
<node CREATED="1689531835390" ID="ID_624354128" MODIFIED="1689531845873" TEXT="IO k&#xf6;nnte auch dort aktivieren"/>
<node CREATED="1689531847156" ID="ID_646303576" MODIFIED="1689531890911" TEXT="Folge-Activities: sp&#xe4;tere Deadline"/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1688337270626" ID="ID_1810148055" MODIFIED="1688337284937" TEXT="&#xbb;BlockFlow&#xab; : Implementation">
@ -79711,8 +79716,8 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<arrowlink COLOR="#eb4070" DESTINATION="ID_1454374119" ENDARROW="Default" ENDINCLINATION="-596;80;" ID="Arrow_ID_208594716" STARTARROW="None" STARTINCLINATION="-331;-16;"/>
<linktarget COLOR="#473acf" DESTINATION="ID_836380061" ENDARROW="Default" ENDINCLINATION="47;-174;" ID="Arrow_ID_166794449" SOURCE="ID_361634809" STARTARROW="None" STARTINCLINATION="-289;16;"/>
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1688510160724" ID="ID_915708936" MODIFIED="1689215731482" TEXT="Activity allozieren">
<icon BUILTIN="pencil"/>
<node COLOR="#338800" CREATED="1688510160724" ID="ID_915708936" MODIFIED="1689528992185" TEXT="Activity allozieren">
<icon BUILTIN="button_ok"/>
<node CREATED="1688510169558" ID="ID_435186748" MODIFIED="1688510256314" TEXT="werden grunds&#xe4;tzlich einzeln behandelt">
<richcontent TYPE="NOTE"><html>
<head>
@ -79732,9 +79737,20 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node CREATED="1688511807398" ID="ID_160731598" MODIFIED="1688511817680" TEXT="erzeugt implizit alle Epochen dazwischen"/>
<node CREATED="1688511820828" ID="ID_1443383285" MODIFIED="1688775531341" TEXT="kann scheitern wenn zu weit in der Zukunft &#x27fc; &#x21af;"/>
</node>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1688559559278" ID="ID_27532065" MODIFIED="1688775478883" TEXT="unklar: kann die Allokation entgleisen?">
<arrowlink COLOR="#fd1a6e" DESTINATION="ID_1315709817" ENDARROW="Default" ENDINCLINATION="21;-31;" ID="Arrow_ID_1483237280" STARTARROW="None" STARTINCLINATION="-205;14;"/>
<icon BUILTIN="flag-pink"/>
<node BACKGROUND_COLOR="#e7cbb5" COLOR="#ff0000" CREATED="1688559559278" ID="ID_27532065" MODIFIED="1689529093491">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
Entscheidung: Allokation entgleist nur<i>&#160;ausnahmsweise</i>
</p>
</body>
</html>
</richcontent>
<arrowlink COLOR="#fd1a6e" DESTINATION="ID_1315709817" ENDARROW="Default" ENDINCLINATION="21;-31;" ID="Arrow_ID_1483237280" STARTARROW="None" STARTINCLINATION="-248;12;"/>
<icon BUILTIN="yes"/>
</node>
<node COLOR="#338800" CREATED="1688560442660" ID="ID_143148462" MODIFIED="1689215725196" TEXT="Activity placement-New">
<icon BUILTIN="button_ok"/>
@ -79747,11 +79763,8 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1688511891911" ID="ID_604517829" MODIFIED="1688511905225" TEXT="sp&#xe4;teste derzeit unterst&#xfc;tzte Deadline">
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1688512195210" ID="ID_455793213" MODIFIED="1688512207091" TEXT="Aufr&#xe4;umen vor gegebener Zeit">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1688512195210" ID="ID_455793213" MODIFIED="1689528962316" TEXT="Aufr&#xe4;umen vor gegebener Zeit">
<icon BUILTIN="button_ok"/>
<node CREATED="1688775777543" ID="ID_827708076" MODIFIED="1688775793070" TEXT="wird ausgel&#xf6;st in der TICK-Activity">
<icon BUILTIN="info"/>
</node>
@ -79808,8 +79821,8 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node COLOR="#338800" CREATED="1688515974697" ID="ID_1054833524" MODIFIED="1689296818673" TEXT="h&#xe4;lt eine ExtentFamily&lt;Activity,siz&gt;">
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1688555107931" ID="ID_285024973" MODIFIED="1688862187262" TEXT="Datentyp: Epoch">
<icon BUILTIN="pencil"/>
<node COLOR="#338800" CREATED="1688555107931" ID="ID_285024973" MODIFIED="1689528942853" TEXT="Datentyp: Epoch">
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1688555141913" ID="ID_406773800" MODIFIED="1689296815496" TEXT="als Subtyp der Extent-Storage">
<icon BUILTIN="button_ok"/>
</node>
@ -79833,8 +79846,8 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1689246500734" ID="ID_1611070672" MODIFIED="1689265537668" TEXT="Zugriff / Navigation">
<icon BUILTIN="pencil"/>
<node COLOR="#338800" CREATED="1689246500734" ID="ID_1611070672" MODIFIED="1689528941556" TEXT="Zugriff / Navigation">
<icon BUILTIN="button_ok"/>
<node COLOR="#435e98" CREATED="1689246852684" ID="ID_1894820075" MODIFIED="1689468776989" TEXT="Problemlage">
<icon BUILTIN="info"/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1689246509452" ID="ID_1697713434" MODIFIED="1689468773371">
@ -79886,10 +79899,10 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1689248121694" ID="ID_1139194353" MODIFIED="1689248191851" TEXT="Zugriffs-Hierarchie: Allocator::iterator &#x29d0; EpochIter &#x29d0; Epoch&amp;">
<icon BUILTIN="forward"/>
<node COLOR="#435e98" CREATED="1689248200483" ID="ID_1272289829" MODIFIED="1689265563074" TEXT="&#x27f9; Konsequenz: Extent&amp; nicht eigenst&#xe4;ndig verwenden"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1689248250300" ID="ID_652125369" MODIFIED="1689248275834" TEXT="Epoch wird dann alle Abk&#xfc;rzungen und Hilfsfunktionen tragen">
<node COLOR="#435e98" CREATED="1689248250300" ID="ID_652125369" MODIFIED="1689528903260" TEXT="Epoch wird dann alle Abk&#xfc;rzungen und Hilfsfunktionen tragen">
<icon BUILTIN="idea"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1689248380839" ID="ID_215002237" MODIFIED="1689248398479" TEXT="BlockFlow stellt dann nur die grundlegenden Konverter bereit">
<node COLOR="#435e98" CREATED="1689248380839" ID="ID_215002237" MODIFIED="1689528937911" TEXT="BlockFlow ist nur f&#xfc;r die Darstellung als Epoch und das Epoch-Spacing zust&#xe4;ndig">
<icon BUILTIN="yes"/>
</node>
<node COLOR="#435e98" CREATED="1689248522225" FOLDED="true" ID="ID_1824695865" MODIFIED="1689265504640" TEXT="problematisches Layering der Iteratoren">
@ -79994,7 +80007,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
</node>
<node COLOR="#338800" CREATED="1689469187413" ID="ID_855611178" MODIFIED="1689523118559" TEXT="Weiterschalten beim Epoch-Overflow">
<arrowlink COLOR="#9d344c" DESTINATION="ID_586190414" ENDARROW="Default" ENDINCLINATION="-456;-39;" ID="Arrow_ID_1282441869" STARTARROW="None" STARTINCLINATION="-78;65;"/>
<arrowlink COLOR="#34819d" DESTINATION="ID_586190414" ENDARROW="Default" ENDINCLINATION="-456;-39;" ID="Arrow_ID_1282441869" STARTARROW="None" STARTINCLINATION="-78;65;"/>
<icon BUILTIN="button_ok"/>
<node COLOR="#435e98" CREATED="1689469246381" ID="ID_797279135" MODIFIED="1689522750277" STYLE="fork" TEXT="zwei verschiedene Aktionen">
<font NAME="SansSerif" SIZE="12"/>
@ -80010,8 +80023,8 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node COLOR="#338800" CREATED="1689469291822" ID="ID_1957125180" MODIFIED="1689522748787" TEXT="neuen Slot einrichten">
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1689469296726" ID="ID_767704093" MODIFIED="1689469309046" TEXT="Overflow-Signal ausl&#xf6;sen">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1689469296726" ID="ID_767704093" MODIFIED="1689528839593" TEXT="Overflow-Signal ausl&#xf6;sen">
<icon BUILTIN="button_ok"/>
</node>
</node>
</node>
@ -80029,10 +80042,10 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1688516187452" ID="ID_843039397" MODIFIED="1688516195292" TEXT="Zusatz-Infos zu verwalten">
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1688516199288" ID="ID_1824919687" MODIFIED="1688516212258" TEXT="Epochen-Deadline">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1688516187452" ID="ID_843039397" MODIFIED="1689528833423" TEXT="Zusatz-Infos zu verwalten">
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1688516199288" ID="ID_1824919687" MODIFIED="1689528828766" TEXT="Epochen-Deadline">
<icon BUILTIN="button_ok"/>
<node CREATED="1688516220648" ID="ID_1169377280" MODIFIED="1688516237353" TEXT="steht in einem Gate im 1.Slot"/>
<node COLOR="#435e98" CREATED="1688553471328" HGAP="24" ID="ID_262514506" MODIFIED="1689296881046" TEXT="daf&#xfc;r eigenen Sub-Typ anliegen: EpochGate" VSHIFT="7">
<linktarget COLOR="#336987" DESTINATION="ID_262514506" ENDARROW="Default" ENDINCLINATION="-88;-7;" ID="Arrow_ID_1549134996" SOURCE="ID_805170537" STARTARROW="None" STARTINCLINATION="57;6;"/>
@ -80068,8 +80081,8 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1688554963598" ID="ID_708490850" MODIFIED="1688554971708" TEXT="F&#xfc;llstand der Epoche">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1688554963598" ID="ID_708490850" MODIFIED="1689528831151" TEXT="F&#xfc;llstand der Epoche">
<icon BUILTIN="button_ok"/>
<node CREATED="1688554972581" ID="ID_278561305" MODIFIED="1688554979689" TEXT="wird auch im EpochGate abgelegt"/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1688777569396" ID="ID_1723162290" MODIFIED="1689303080773" TEXT="schwierig... Platz fehlt">
<icon BUILTIN="messagebox_warning"/>
@ -80195,15 +80208,21 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1689204430524" ID="ID_1525654861" MODIFIED="1689204437235" TEXT="Signale">
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1689204438866" ID="ID_586190414" MODIFIED="1689204458016" TEXT="Epochen-Overflow">
<linktarget COLOR="#9d344c" DESTINATION="ID_586190414" ENDARROW="Default" ENDINCLINATION="-456;-39;" ID="Arrow_ID_1282441869" SOURCE="ID_855611178" STARTARROW="None" STARTINCLINATION="-78;65;"/>
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1689204438866" ID="ID_586190414" MODIFIED="1689528725978" TEXT="Epochen-Overflow">
<linktarget COLOR="#34819d" DESTINATION="ID_586190414" ENDARROW="Default" ENDINCLINATION="-456;-39;" ID="Arrow_ID_1282441869" SOURCE="ID_855611178" STARTARROW="None" STARTINCLINATION="-78;65;"/>
<icon BUILTIN="button_ok"/>
<node CREATED="1689355428408" ID="ID_1439608393" MODIFIED="1689355463591" TEXT="bei jedem Event um einen proprotionalen Faktor verk&#xfc;rzen"/>
<node CREATED="1689355466427" ID="ID_966913305" MODIFIED="1689355486380" TEXT="verk&#xfc;rzen &#x27f9; Slot-Dichte um den Kehrwert erh&#xf6;ht"/>
<node CREATED="1689355589282" ID="ID_840744" MODIFIED="1689355613393" TEXT="Faktor? &#x3a6; nat&#xfc;rlich">
<icon BUILTIN="ksmiletris"/>
<node CREATED="1689355589282" ID="ID_840744" MODIFIED="1689528652859" TEXT="Faktor? &#x3a6; nat&#xfc;rlich">
<icon BUILTIN="button_cancel"/>
<node CREATED="1689356180333" ID="ID_71577757" MODIFIED="1689356511458" TEXT="1/&#x3a6; = &#x3a6;-1"/>
<node CREATED="1689356185098" ID="ID_1224416689" MODIFIED="1689356203787" TEXT="0,6180339887498948482"/>
<node CREATED="1689528655142" ID="ID_1594941219" MODIFIED="1689528667779" TEXT="Nein! das w&#xe4;re zu aggressiv">
<icon BUILTIN="stop-sign"/>
</node>
</node>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#190f69" CREATED="1689528669251" ID="ID_1236093000" MODIFIED="1689528715267" TEXT="w&#xe4;hle mal erst was Einfaches: Faktor 0.9">
<icon BUILTIN="forward"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1689204448250" ID="ID_688039501" MODIFIED="1689204458017" TEXT="F&#xfc;llstand beim Aufr&#xe4;umen">
@ -80226,7 +80245,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1688559356693" HGAP="9" ID="ID_1823374976" MODIFIED="1688559375797" TEXT="Grenzf&#xe4;lle" VSHIFT="7">
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1688559379394" ID="ID_1315709817" MODIFIED="1688560429832" TEXT="zu weit in der Zukunft">
<linktarget COLOR="#fd1a6e" DESTINATION="ID_1315709817" ENDARROW="Default" ENDINCLINATION="21;-31;" ID="Arrow_ID_1483237280" SOURCE="ID_27532065" STARTARROW="None" STARTINCLINATION="-205;14;"/>
<linktarget COLOR="#fd1a6e" DESTINATION="ID_1315709817" ENDARROW="Default" ENDINCLINATION="21;-31;" ID="Arrow_ID_1483237280" SOURCE="ID_27532065" STARTARROW="None" STARTINCLINATION="-248;12;"/>
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1688559400839" ID="ID_980233005" MODIFIED="1688559420337" TEXT="problematisch: es kann nicht wirklich alloziert werden"/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1688559421309" ID="ID_498818717" MODIFIED="1688774030997">