Scheduler-test: fix out-of-bound access

...causing the system to freeze due to excess memory allocation.

Fortunately it turned out this was not an error in the Scheduler core
or memory manager, but rather a sloppiness in the test scaffolding.
However, this incident highlights that the memory manager lacks some
sanity checks to prevent outright nonsensical allocation requests.

Moreover it became clear again that the allocation happens ''already before''
entering the Scheduler — and thus the existing sanity check comes too late.
Now I've used the same reasoning also for additional checks in the allocator,
limiting the Epoch increment to 3000 and the total memory allocation to 8GiB

Talking of Gibitbytes...
indeed we could use a shorthand notation for that purpose...
This commit is contained in:
Fischlurch 2023-12-21 20:24:51 +01:00
parent cca9787e08
commit 2cd51fa714
7 changed files with 697 additions and 16 deletions

View file

@ -429,6 +429,7 @@ namespace util {
std::string showDouble (double) noexcept;
std::string showFloat (float) noexcept;
std::string showSize (size_t) noexcept;
@ -464,4 +465,28 @@ namespace util {
}// namespace util
/* === Literals for common size designations === */
inline uint
operator""_KiB (unsigned long long const siz)
{
return uint(siz) * 1024u;
}
inline uint
operator""_MiB (unsigned long long const siz)
{
return uint(siz) * 1024u*1024u;
}
inline unsigned long long
operator""_GiB (unsigned long long const siz)
{
return siz * 1024uLL*1024uLL*1024uLL;
}
#endif /*LIB_META_UTIL_H*/

View file

@ -106,9 +106,21 @@ namespace gear {
using lib::time::Duration;
using lib::time::FrameRate;
namespace err = lumiera::error;
namespace blockFlow {///< Parametrisation of Scheduler memory management scheme
/** limit for maximum number of blocks allowed in Epoch expansion
* @note SchedulerCommutator::sanityCheck() defines a similar limit,
* but there the same reasoning is translated into a hard limit for
* deadlines to be < 20sec, while this limit here will only be triggered
* if the current block duration has been lowered to the OVERLOAD_LIMIT
* @see scheduler-commutator.hpp
*/
const size_t BLOCK_EXPAND_SAFETY_LIMIT = 3000;
/**
* Lightweight yet safe parametrisation of memory management.
* Used as default setting and thus for most tests.
@ -484,6 +496,7 @@ namespace gear {
EpochIter nextEpoch{alloc_.end()};
ENSURE (not nextEpoch); // not valid yet, but we will allocate starting there...
auto requiredNew = distance / _raw(epochStep_);
___sanityCheckAlloc(requiredNew);
if (distance % _raw(epochStep_) > 0)
++requiredNew; // fractional: requested deadline lies within last epoch
alloc_.openNew(requiredNew); // Note: nextEpoch now points to the first new Epoch
@ -643,6 +656,16 @@ namespace gear {
}
TimeVar pastDeadline_{Time::ANYTIME};
void
___sanityCheckAlloc (size_t newBlockCnt)
{
if (newBlockCnt > blockFlow::BLOCK_EXPAND_SAFETY_LIMIT)
throw err::Fatal{"Deadline expansion causes allocation of "
+util::showSize(newBlockCnt) +"blocks > "
+util::showSize(blockFlow::BLOCK_EXPAND_SAFETY_LIMIT)
, err::LUMIERA_ERROR_CAPACITY};
}
/// „backdoor“ to watch internals from tests
friend class FlowDiagnostic<CONF>;

View file

@ -56,6 +56,10 @@
namespace vault{
namespace mem {
namespace {
const size_t ALLOC_SAFETY_LIMIT = 8_GiB;
}
using util::unConst;
template<typename T, size_t siz>
@ -198,6 +202,7 @@ namespace mem {
size_t addSiz = cnt - freeSlotCnt()
+ EXCESS_ALLOC;
// add a strike of new extents at the end
___sanityCheckAllocSize (addSiz);
extents_.resize (oldSiz + addSiz);
if (isWrapped())
{// need the new elements in the middle, before the existing start_
@ -317,6 +322,19 @@ namespace mem {
return unConst(this)->extents_[idx].access();
} // deliberately const-ness does not cover payload
void
___sanityCheckAllocSize (size_t addCnt)
{
size_t resultSiz = slotCnt()+addCnt;
size_t requiredSpace = resultSiz * sizeof(Extent);
using namespace lumiera::error;
if (requiredSpace > ALLOC_SAFETY_LIMIT)
throw Fatal{"Raw allocation exceeds safety limit: "
+util::showSize(requiredSpace) +" > "
+util::showSize(ALLOC_SAFETY_LIMIT)
, LUMIERA_ERROR_CAPACITY};
}
/// „backdoor“ to watch internals from tests
friend class ExtentDiagnostic<T,siz>;

View file

@ -79,8 +79,6 @@
namespace stage {
namespace error = lumiera::error;
using error::LUMIERA_ERROR_ASSERTION;
using lib::test::EventLog;
using lib::test::EventMatch;

View file

@ -84,9 +84,10 @@ namespace test {
smokeTest()
{
MARK_TEST_FUN
TestChainLoad testLoad{64};
TestChainLoad testLoad{128};
testLoad.configureShape_chain_loadBursts()
.buildToplolgy();
.buildToplolgy()
.printTopologyDOT();
auto stats = testLoad.computeGraphStatistics();
cout << _Fmt{"Test-Load: Nodes: %d Levels: %d ∅Node/Level: %3.1f Forks: %d Joins: %d"}
@ -119,7 +120,7 @@ namespace test {
double performanceTime =
testLoad.setupSchedule(scheduler)
.withLoadTimeBase(LOAD_BASE)
.withJobDeadline(30ms)
.withJobDeadline(50ms)
.launch_and_wait();
cout << "runTime(Scheduler): "<<performanceTime/1000<<"ms"<<endl;

View file

@ -1818,8 +1818,9 @@ namespace test {
size_t
calcNextChunkEnd (size_t lastNodeIDX)
{
return lastNodeIDX + chunkSize_;
}
lastNodeIDX += chunkSize_;
return min (lastNodeIDX, chainLoad_.size()-1);
} // prevent out-of-bound access
Time
calcStartTime(size_t level)
@ -1836,6 +1837,7 @@ namespace test {
dependencies to the last row of the preceding chunk, implying that
those still need to be ahead of schedule, and not yet dispatched.
*/
lastNodeIDX = min (lastNodeIDX, chainLoad_.size()-1); // prevent out-of-bound access
size_t nextChunkLevel = chainLoad_.nodes_[lastNodeIDX].level;
nextChunkLevel = nextChunkLevel>2? nextChunkLevel-2 : 0;
return calcStartTime(nextChunkLevel) - _uTicks(preRoll_);

View file

@ -57587,6 +57587,102 @@
<arrowlink COLOR="#3f76e9" DESTINATION="ID_333704322" ENDARROW="Default" ENDINCLINATION="-542;0;" ID="Arrow_ID_1390962202" STARTARROW="None" STARTINCLINATION="183;24;"/>
</node>
</node>
<node CREATED="1703172700758" ID="ID_1761309044" MODIFIED="1703172707726" TEXT="notation">
<node CREATED="1703172741792" ID="ID_1189429252" MODIFIED="1703172746276" TEXT="stylistic">
<node CREATED="1703172747431" ID="ID_485097601" MODIFIED="1703172750563" TEXT="const&amp;"/>
<node CREATED="1703172755678" ID="ID_272935643" MODIFIED="1703172765633" TEXT="and, or, not"/>
<node CREATED="1703172795447" ID="ID_1649043889" MODIFIED="1703172801436" TEXT="uint statt unsigned int"/>
</node>
<node CREATED="1703172823421" ID="ID_1409650651" MODIFIED="1703172825657" TEXT="conversions">
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1703172828444" ID="ID_1058839767" MODIFIED="1703172842384" TEXT="Ort der Definition?">
<node CREATED="1703172844395" ID="ID_61826892" MODIFIED="1703173118168" TEXT="schwierige Frage">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
..zum einen der Namespace: das f&#252;hrt dann zu using-Klauseln an vielen Stellen
</p>
<p>
...au&#223;erdem die Sichtbarkeit: solche Definitionen erzeugen einen Sog
</p>
</body>
</html>
</richcontent>
</node>
<node CREATED="1703173121483" ID="ID_1370044893" MODIFIED="1703177409659" TEXT="versuche erst mal lib/meta/util.hpp">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
...und zwar, weil <i>for all practical purposes </i>entweder igendwo iteriert wird (iter-adapter sind includiert) oder&#160;eine Format-Operation stattfindet oder zumindest&#160;eines der elementaren Metaprogrammnig-Hilfsmittel indirekt zum Einsatz kommt. D.h. die Wahrscheinlichkeit, da&#223; lib/meta/util.hpp &#187;zuf&#228;llig schon&#171; includiert wird, ist hoch, und damit kann <i>dieser S&#252;ndenfall unter dem Radar fliegen</i>
</p>
</body>
</html>
</richcontent>
</node>
<node CREATED="1703177196593" ID="ID_534216369" MODIFIED="1703177240576" TEXT="und in den top namespace">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
solange es nur limitiert genutzt wird, ist mir das lieber, als einen zentralen Header zu schaffen, der dann &#252;berall includiert wird und Begehrlichkeiten wecken k&#246;nnte
</p>
</body>
</html>
</richcontent>
</node>
</node>
<node CREATED="1703173134835" ID="ID_1080785547" MODIFIED="1703173155885" TEXT="_KiB _MiB _GiB">
<node CREATED="1703173168935" ID="ID_1852546854" LINK="https://stackoverflow.com/a/39622579/444796" MODIFIED="1703173201402" TEXT="Anregung(SO)"/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1703173304860" ID="ID_468031830" MODIFIED="1703176899183" TEXT="Vorsicht: Wertebereich">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
lb(1GiB) &#8801; 30
</p>
<p>
wrap-around droht
</p>
</body>
</html>
</richcontent>
<arrowlink COLOR="#7da0ba" DESTINATION="ID_325823218" ENDARROW="Default" ENDINCLINATION="-881;88;" ID="Arrow_ID_420115024" STARTARROW="None" STARTINCLINATION="-1677;171;"/>
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1703176930217" ID="ID_1488856714" MODIFIED="1703177011017" TEXT="signed values sind strategisch g&#xfc;nstiger f&#xfc;r Arithmetik"/>
<node CREATED="1703177011750" ID="ID_1750660554" MODIFIED="1703177184275" TEXT="da wir aber hier mit Gr&#xf6;&#xdf;en operieren, verwende ich unsigned">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<ul>
<li>
bei Zuweisung an einen signed-Type passiert automatische Konversion (potentiell gef&#228;hrlich).
</li>
<li>
in einem Ausdruck setzt sich der <i>Unsigned</i>&#160;durch (es sei denn, das andere Argument hat einen gr&#246;&#223;eren Wertebereich)
</li>
<li>
Vergleiche erzeugen signed-unsigned-Warnings &#8212; aus <b>praktischen Gr&#252;nden ist das f&#252;r mich ausschlaggebend</b>
</li>
</ul>
</body>
</html>
</richcontent>
</node>
</node>
</node>
</node>
</node>
<node CREATED="1573230456930" ID="ID_1636521851" MODIFIED="1573230459836" TEXT="utils">
<node CREATED="1573230461194" ID="ID_225640230" MODIFIED="1573230465260" TEXT="knapp halten">
<icon BUILTIN="yes"/>
@ -57613,6 +57709,15 @@
<icon BUILTIN="yes"/>
</node>
</node>
<node CREATED="1703172896502" ID="ID_554153272" MODIFIED="1703172900903" TEXT="Code-Organisation">
<node CREATED="1703172903191" ID="ID_889300693" MODIFIED="1703172976445" TEXT="avoid ultimative top-level">
<node CREATED="1703172989855" ID="ID_1185412954" MODIFIED="1703172994032" TEXT="notorious and problematic">
<node CREATED="1703172995726" ID="ID_646721098" MODIFIED="1703172998738" TEXT="error.hpp"/>
<node CREATED="1703172999949" ID="ID_1980565287" MODIFIED="1703173004881" TEXT="lib/util.hpp"/>
<node CREATED="1703173005517" ID="ID_1190786260" MODIFIED="1703173011755" TEXT="lib/meta/util.hpp"/>
</node>
</node>
</node>
<node CREATED="1696123512914" ID="ID_1907944246" MODIFIED="1696123517031" TEXT="Fehlerbehandlung">
<node CREATED="1696123519551" ID="ID_1260806652" MODIFIED="1696123525010" TEXT="Status-quo">
<node CREATED="1696123526614" ID="ID_494414016" MODIFIED="1696123536532" TEXT="zwei konkurrierende Systeme"/>
@ -83060,17 +83165,37 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</p>
</body>
</html></richcontent>
<linktarget COLOR="#2f4758" DESTINATION="ID_169718532" ENDARROW="Default" ENDINCLINATION="454;1825;" ID="Arrow_ID_309449594" SOURCE="ID_166453307" STARTARROW="None" STARTINCLINATION="-750;-32;"/>
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1699373956162" ID="ID_1098257299" MODIFIED="1699376259965" TEXT="ebenso einen Check gegen Deadlines zu weit in der Zukunft">
<icon BUILTIN="button_ok"/>
<node CREATED="1699373969470" ID="ID_396517654" MODIFIED="1699373978929" TEXT="sinnvoll dimensionieren?"/>
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1699373980509" ID="ID_1475597715" MODIFIED="1699373990484" TEXT="man k&#xf6;nnte hier auf den BlockFlow zugreifen">
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1699373980509" ID="ID_1475597715" MODIFIED="1703168308712" TEXT="man k&#xf6;nnte hier auf den BlockFlow zugreifen">
<richcontent TYPE="NOTE"><html>
<head/>
<body>
<p>
Das <i>k&#246;nnte </i>man machen, klingt sogar sinnvoll &#8212; ABER...
</p>
<p>
Der BlockFlow m&#252;&#223;te dann seine eigene Config dynamischer auswerten. Das mit der Config war ein schwieriges Thema, denn ich wollte sie statisch haben, und das hat sich dann auch als sehr performance-relevant best&#228;tigt. Daher m&#246;chte ich das Thema mit einer dynamischen Auswertung vertagen, bis wir insgesamt ein klareres Bild zum Thema System-Konfiguration haben.
</p>
<br/>
<p>
Die L&#246;sung m&#252;&#223;te in etwa so aussehen: Der BlockFlow hat dann eine Informationsfuntion, die ebenfalls auf die statische Config zugreift, und eben jeden &#220;berschlags-Berechnungen macht, die ich hier nun mit dem Taschenrechner gemacht habe. Das w&#252;rde nat&#252;rlich eine Requirement-Analyse vorraussetzen, d.h. welche Informationen werden ben&#246;tigt? Im Moment ist der Scheduler der einzige &#187;Kunde&#171;.
</p>
<br/>
<p>
Hinzu kommt, da&#223; dies hier ohnehin ein <i>zus&#228;tzliches Sicherheitsnetz</i>&#160;ist: um den BlockFlow auf die minimale Blockgr&#246;&#223;e zu dr&#252;cken, m&#252;&#223;te man den Scheduler <i>massivst &#252;berladen; </i>er w&#252;rde dann vermutlich die Deadline vom n&#228;chsten &#187;Tick&#171; &#252;berfahren, und dann eine &#187;Scheduler-emergency&#171; ausl&#246;sen (da der Tick<i>&#160;&#160;compulsory </i>ist). Das w&#252;rde nach ca. 0.5 Sekunden passieren; hier aber reden wir &#252;ber 20 Sekunden mit dieser Dichte. Es geht also im Grunde nur darum, da&#223; das System kurzzeitige Lasts&#246;&#223;e &#252;berlebt, ohne aus dem Gleichgewicht zu kommen
</p>
</body>
</html></richcontent>
<icon BUILTIN="hourglass"/>
</node>
<node CREATED="1699373991478" ID="ID_167847312" MODIFIED="1699376244923" TEXT="erst mal fest verdrahten">
<icon BUILTIN="yes"/>
<node CREATED="1699373997383" ID="ID_680337402" MODIFIED="1699374014940" TEXT="Block-Size: 500 &#x27f9; Frames pro Block"/>
<node CREATED="1699373997383" ID="ID_680337402" MODIFIED="1703167502633" TEXT="Block-Size: 500 &#x27f9; 50 Frames pro Block"/>
<node CREATED="1699374069953" ID="ID_987216063" MODIFIED="1699374077213" TEXT="initial Framerate: 5 * 25"/>
<node CREATED="1699374241946" ID="ID_854095581" MODIFIED="1699374250957" TEXT="&#x27f9; initial Epoch-Step 0.4sec"/>
<node CREATED="1699374286828" ID="ID_1273383304" MODIFIED="1699374296403" TEXT="&#x27f9; Limit bei 6666&#xb5;s"/>
@ -105595,6 +105720,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
<node COLOR="#435e98" CREATED="1703029832104" ID="ID_592804815" MODIFIED="1703037364626" TEXT="Testl&#xe4;ufe">
<node COLOR="#435e98" CREATED="1703029837383" FOLDED="true" ID="ID_728556946" MODIFIED="1703037346853" TEXT="Groooming-Token durcheinander">
<linktarget COLOR="#955269" DESTINATION="ID_728556946" ENDARROW="Default" ENDINCLINATION="339;27;" ID="Arrow_ID_1122005137" SOURCE="ID_728405176" STARTARROW="None" STARTINCLINATION="-478;-13;"/>
<icon BUILTIN="broken-line"/>
<node CREATED="1703030898754" ID="ID_985851431" MODIFIED="1703032124763" TEXT="generell: durch die letzte &#xc4;nderung haben wir nun MASSIVE contention">
<icon BUILTIN="info"/>
@ -106342,9 +106468,9 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<icon BUILTIN="yes"/>
</node>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1702945920119" ID="ID_663842775" MODIFIED="1703121651317" TEXT="Kapazit&#xe4;ts-Fokus im WORK_HORIZON">
<icon BUILTIN="pencil"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1702945939808" ID="ID_1722566858" MODIFIED="1703121645904" TEXT="Idee: gem&#xe4;&#xdf; Abstand zur Head-Time fokussieren">
<node COLOR="#338800" CREATED="1702945920119" ID="ID_663842775" MODIFIED="1703185979127" TEXT="Kapazit&#xe4;ts-Fokus im WORK_HORIZON">
<icon BUILTIN="button_ok"/>
<node COLOR="#435e98" CREATED="1702945939808" ID="ID_1722566858" MODIFIED="1703185984692" TEXT="Idee: gem&#xe4;&#xdf; Abstand zur Head-Time fokussieren">
<icon BUILTIN="idea"/>
<node CREATED="1703121466136" ID="ID_1443341840" MODIFIED="1703121471090" TEXT="welche Regel?"/>
<node CREATED="1703121471967" ID="ID_516479533" MODIFIED="1703121640145" TEXT="so einfach wie m&#xf6;glich!">
@ -106401,8 +106527,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
das ist aber keine dramatische Verschlechterung, vielmehr nur sichtbar, wenn man genau nachrechnet
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node CREATED="1703124282757" ID="ID_1715598274" MODIFIED="1703124340578" TEXT="immer wenn wir behind-of-schedule fallen, tauchen nun Schw&#xe4;rme von Workern auf...."/>
<node CREATED="1703124341541" ID="ID_1452683883" MODIFIED="1703124357138" TEXT="...und condenden f&#xfc;r kurze Zeit (~200&#xb5;s)"/>
@ -106541,8 +106666,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
&#160;&#160;&#160;&#183;&#8214; E0: @8096 HT:0&#160;&#160;-&gt; &#8728;
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<icon BUILTIN="list"/>
<node CREATED="1703126920139" ID="ID_1308227154" MODIFIED="1703126929353" TEXT="erster Planungs-Chunk l&#xe4;uft durch"/>
<node CREATED="1703126930277" ID="ID_1052496667" MODIFIED="1703126939556" TEXT="Nodes tauchen w&#xe4;hrenddessen auf und pendeln sich ein"/>
@ -106557,9 +106681,448 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<icon BUILTIN="full-1"/>
</node>
<node CREATED="1703127271693" ID="ID_1738697191" MODIFIED="1703127300635" TEXT="Job weit in der Zukunft: Memory-Manager l&#xe4;uft aus dem Ruder">
<linktarget COLOR="#943b96" DESTINATION="ID_1738697191" ENDARROW="Default" ENDINCLINATION="-55;65;" ID="Arrow_ID_1998217905" SOURCE="ID_1971806311" STARTARROW="None" STARTINCLINATION="-218;-17;"/>
<icon BUILTIN="full-2"/>
</node>
</node>
<node CREATED="1703162471755" ID="ID_1474633981" MODIFIED="1703162477115" TEXT="Untersuchung">
<node CREATED="1703162478461" ID="ID_1830137376" MODIFIED="1703162489367" TEXT="per Debugger stoppen">
<node CREATED="1703162496341" ID="ID_1392051462" MODIFIED="1703162521307" TEXT="1.Lauf">
<node CREATED="1703162522301" ID="ID_453241707" MODIFIED="1703162531401" TEXT="best&#xe4;tigt: wir stehen in einer Allokation"/>
<node CREATED="1703162532581" ID="ID_1421857785" MODIFIED="1703162610528" TEXT="Call-Stack ging durch vault::mem::Storage-ctor">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
extent-family.hpp line 105
</p>
</body>
</html>
</richcontent>
</node>
<node CREATED="1703162766757" ID="ID_1945856466" MODIFIED="1703162789606" TEXT="es ist der Planner-Thread (Testsuite-Thread)"/>
<node CREATED="1703162854130" ID="ID_180598415" MODIFIED="1703162863361" TEXT="Aufruf aus einer std::vector-Operation"/>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#bc9680" CREATED="1703162631935" ID="ID_1846367411" MODIFIED="1703162664780" TEXT="Debugger-crash">
<icon BUILTIN="smily_bad"/>
</node>
</node>
<node CREATED="1703162953692" ID="ID_190335632" MODIFIED="1703162956943" TEXT="2.Lauf">
<node CREATED="1703162959003" ID="ID_535055599" MODIFIED="1703163050775" TEXT="Call ging durch ExtentFamily::openNew() &#x2023; extents_.resize (oldSiz + addSiz);">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
extent-family.hpp l.201
</p>
</body>
</html>
</richcontent>
</node>
<node CREATED="1703163096313" ID="ID_869110521" MODIFIED="1703163896219" STYLE="bubble">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
<font face="Monospaced" size="2">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;if (not canAccomodate (cnt)) </font>
</p>
<p>
<font face="Monospaced" size="2">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;{//</font><font face="Monospaced" size="2" color="#460e73">insufficient reserve =&gt; allocate</font><font face="Monospaced" size="2">&#160;</font>
</p>
<p>
<font face="Monospaced" size="2">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;size_t oldSiz = slotCnt(); </font>
</p>
<p>
<font face="Monospaced" size="2">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;size_t addSiz = cnt - freeSlotCnt() </font>
</p>
<p>
<font face="Monospaced" size="2">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;+ EXCESS_ALLOC; </font>
</p>
<p>
<font face="Monospaced" size="2">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;// add a strike of new extents at the end </font>
</p>
<p>
<font color="#940147" face="Monospaced" size="2">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;extents_.resize (oldSiz + addSiz); </font>
</p>
</body>
</html>
</richcontent>
<icon BUILTIN="idea"/>
</node>
<node CREATED="1703163200679" ID="ID_1971806311" MODIFIED="1703163242808" TEXT="das sieht ehr nach Hypothese-2 aus...">
<arrowlink COLOR="#943b96" DESTINATION="ID_1738697191" ENDARROW="Default" ENDINCLINATION="-55;65;" ID="Arrow_ID_1998217905" STARTARROW="None" STARTINCLINATION="-218;-17;"/>
<font ITALIC="true" NAME="SansSerif" SIZE="12"/>
</node>
</node>
<node CREATED="1703163527874" ID="ID_389476092" MODIFIED="1703163531194" TEXT="3.Lauf">
<node CREATED="1703163537400" ID="ID_1729162058" MODIFIED="1703163539250" TEXT="Ha!">
<node CREATED="1703163540750" ID="ID_378049319" MODIFIED="1703164871719" TEXT="cnt size_t = 62911609">
<font NAME="Monospaced" SIZE="12"/>
</node>
</node>
<node COLOR="#7e653d" CREATED="1703163617059" ID="ID_653314426" MODIFIED="1703163636988" TEXT="wir gratulieren">
<icon BUILTIN="smiley-oh"/>
</node>
<node CREATED="1703163766767" ID="ID_188603532" MODIFIED="1703166659215" TEXT="Call kommt direkt aus BlockFlow::until()">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
block-flow.hpp, line 489
</p>
</body>
</html>
</richcontent>
<node CREATED="1703163824208" ID="ID_1430199254" MODIFIED="1703163940173" STYLE="bubble">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
<font face="Monospaced" size="2">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;if (lastEpoch().deadline() &lt; deadline) </font>
</p>
<p>
<font face="Monospaced" size="2">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;{</font><font color="#6d30a4" face="Monospaced" size="2">&#160; &#160;// a deadline beyond the established Epochs... </font>
</p>
<p>
<font color="#6d30a4" face="Monospaced" size="2">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;//&#160;&#160;create a grid of new epochs up to the requested point</font>
</p>
<p>
<font face="Monospaced" size="2">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;TimeVar lastDeadline = lastEpoch().deadline(); </font>
</p>
<p>
<font face="Monospaced" size="2">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;auto distance = _raw(deadline) - _raw(lastDeadline); </font>
</p>
<p>
<font face="Monospaced" size="2">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;EpochIter nextEpoch{alloc_.end()}; </font>
</p>
<p>
<font face="Monospaced" size="2">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;ENSURE (not nextEpoch);&#160;&#160;&#160;&#160;&#160;&#160;// not valid yet, but we will allocate there... </font>
</p>
<p>
<font face="Monospaced" size="2">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;auto requiredNew = distance / _raw(epochStep_); </font>
</p>
<p>
<font face="Monospaced" size="2">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;if (distance % _raw(epochStep_) &gt; 0) </font>
</p>
<p>
<font face="Monospaced" size="2">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;++requiredNew;&#160;&#160;// fractional:&#160;&#160;requested deadline lies within last epoch </font>
</p>
<p>
<font color="#a50404" face="Monospaced" size="2">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;alloc_.openNew(requiredNew);</font>
</p>
</body>
</html>
</richcontent>
</node>
</node>
<node COLOR="#435e98" CREATED="1703163960734" ID="ID_1401525515" MODIFIED="1703165277902" TEXT="fragt sich: ist das der einzige Call oder wer l&#xe4;uft hier davon...?">
<icon BUILTIN="help"/>
<node CREATED="1703164406130" ID="ID_1441798395" MODIFIED="1703164410757" TEXT="Aufruf-Situation">
<node CREATED="1703164432414" ID="ID_666040525" MODIFIED="1703164438833" TEXT="SchedulerCtx::continuation()"/>
<node CREATED="1703164440253" ID="ID_204355511" MODIFIED="1703164448976" TEXT="erster Zweig... es geht weiter">
<node CREATED="1703164450612" ID="ID_1434176183" MODIFIED="1703164470598" TEXT="dieser Code-Zweig ist noch nicht getestet">
<icon BUILTIN="messagebox_warning"/>
</node>
<node CREATED="1703164489598" ID="ID_879331972" MODIFIED="1703164498809" TEXT="lastNodeIDX = 69"/>
<node CREATED="1703164489598" ID="ID_1336847461" MODIFIED="1703164508171" TEXT="nextChunkEndNode = 133"/>
<node CREATED="1703164593912" ID="ID_744639613" MODIFIED="1703164609346" TEXT="&#xd83e;&#xdc32; calcPlanScheduleTime (133)">
<node CREATED="1703164885553" ID="ID_1409059466" MODIFIED="1703164897130" TEXT="133 &gt; 127"/>
</node>
<node CREATED="1703164609982" ID="ID_1280618260" MODIFIED="1703164633255" TEXT="dann KANNs ja gar nicht funktionieren...."/>
</node>
</node>
<node CREATED="1703165105540" ID="ID_52849138" MODIFIED="1703165131629" TEXT="ich hatte gedacht: &#x201e;der Planungs-Funktor wird&apos;s schon richten&#x201c;">
<node CREATED="1703165174381" ID="ID_1496023293" MODIFIED="1703165180616" TEXT="dort ist ja eine for-Schleife"/>
<node CREATED="1703165181154" ID="ID_1424833435" MODIFIED="1703165201555" TEXT="und die begrenzt auf currIdx_&lt;maxCnt_"/>
</node>
<node COLOR="#435e98" CREATED="1703165240202" ID="ID_647474026" MODIFIED="1703165285892">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
<u>Fazit</u>: es ist ein einziger Call &#8212; der verlangt Unm&#246;giches vom Memory-Manager
</p>
</body>
</html>
</richcontent>
<icon BUILTIN="forward"/>
</node>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1703165296882" ID="ID_7085439" MODIFIED="1703165321507" TEXT="Es ist ein Bug im Test-Setup">
<icon BUILTIN="broken-line"/>
<node CREATED="1703165326625" ID="ID_1115864967" MODIFIED="1703165360270" TEXT="der Ziel-Node-Level wird ohne Begrenzungs-Check gesetzt"/>
<node CREATED="1703165362089" ID="ID_45972569" MODIFIED="1703165380667" TEXT="der tats&#xe4;chliche Planungs-Funktor w&#xfc;rde sich im erlaubten Bereich halten"/>
<node CREATED="1703165381495" ID="ID_1561771798" MODIFIED="1703165434620" TEXT="aber vorher wird bereits eine Deadline gesetzt &#x2014; nach Zugriff hinter das Ende der Allokation"/>
</node>
</node>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#4c234d" CREATED="1703165462125" ID="ID_864402378" MODIFIED="1703182885687" TEXT="Schlu&#xdf;folgerungen">
<font BOLD="true" NAME="SansSerif" SIZE="12"/>
<icon BUILTIN="forward"/>
<node CREATED="1703165471587" ID="ID_1259933690" MODIFIED="1703165495541" TEXT="die Steuerung der Planungs-Chunks im Test-Setup mu&#xdf; &#xfc;berarbeitet werden"/>
<node CREATED="1703165506798" ID="ID_1395998021" MODIFIED="1703165628889" TEXT="es r&#xe4;cht sich, da&#xdf; ich an vielen Stellen auf Assertions verzichtet habe (wegen Performance)">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
...es geht hier um Performance-Messungen, die allerdings auch schon im Debug-Build aussagekr&#228;ftig sein sollen (den Release-Build betrachte ich dann als zus&#228;tzlichen Bonus); deshalb habe ich auf viele Sicherheitsma&#223;namen und Diagnose-Hilfsmittel verzichtet, die ich normalerweise in Tests einsetze
</p>
</body>
</html>
</richcontent>
</node>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#b41720" CREATED="1703165632430" ID="ID_716202618" MODIFIED="1703165957783">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
nun schon mehrfach aufgefallen: die Allokationen passieren <i>schon vor </i>der Verarbeitung
</p>
</body>
</html>
</richcontent>
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1703165693469" ID="ID_941115757" MODIFIED="1703165710863" TEXT="das entspricht nicht meinem mentalen Modell"/>
<node CREATED="1703165711432" ID="ID_1162798627" MODIFIED="1703165742803" TEXT="die Steuerlogik (mit bound-check) liegt im Scheduler"/>
<node CREATED="1703165744463" ID="ID_1941418597" MODIFIED="1703165754105" TEXT="an der Stelle ist es aber bereits zu sp&#xe4;t"/>
<node CREATED="1703165997332" ID="ID_310145035" MODIFIED="1703166081651" TEXT="z.B. Commutator::sanityCheck()">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
ist gut, und setzt auch eine Begrenzung durch, die den Allokator vor &#220;berforderung sch&#252;tzen soll, kommt aber leider zu sp&#228;t f&#252;r den Allokator, der ist dann schon tot
</p>
</body>
</html>
</richcontent>
</node>
</node>
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1703165767963" ID="ID_728405176" MODIFIED="1703165937735" TEXT="das war auch schon die Ursache f&#xfc;r die falsche Handhabung des Grooming-Token">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
...hab ich in den letzten Tagen aufgekl&#228;rt und gefixt: das Grooming-Token wurde im Scheduler gedroppt, wird aber im Planungs-Job gebraucht, denn die Allokation erfolgt <b>dort</b>&#160;<i>(also fr&#252;her als gedacht)</i>
</p>
</body>
</html>
</richcontent>
<arrowlink COLOR="#955269" DESTINATION="ID_728556946" ENDARROW="Default" ENDINCLINATION="339;27;" ID="Arrow_ID_1122005137" STARTARROW="None" STARTINCLINATION="-478;-13;"/>
<icon BUILTIN="idea"/>
</node>
</node>
<node COLOR="#338800" CREATED="1703166426828" ID="ID_1981122985" MODIFIED="1703182867176" TEXT="Fixes">
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1703166432260" ID="ID_1609345434" MODIFIED="1703182631453" TEXT="Guard in die Continuation einbauen">
<icon BUILTIN="button_ok"/>
<node COLOR="#2dacc6" CREATED="1703182497384" ID="ID_1852730225" MODIFIED="1703182627521" TEXT="der Teil ist banal...">
<icon BUILTIN="smiley-neutral"/>
</node>
<node COLOR="#338800" CREATED="1703182592371" ID="ID_1927716217" MODIFIED="1703182616282" TEXT="limitiere in calcNextChunkEnd()">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1703182503855" ID="ID_1692200477" MODIFIED="1703182614884" TEXT="baue zur Dokumentation auch Limit ein in calcPlanScheduleTime()">
<icon BUILTIN="button_ok"/>
</node>
</node>
<node COLOR="#338800" CREATED="1703166473342" ID="ID_886521553" MODIFIED="1703182235528" TEXT="das im Scheduler gesetzte Limit auch im BlockFlow pr&#xfc;fen">
<icon BUILTIN="button_ok"/>
<node CREATED="1703166874337" ID="ID_1594271948" MODIFIED="1703166928869" TEXT="sanityCheck: eingef&#xfc;hrt in 892099">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
commit 892099412cdf171d9a7f960c4a5e2d2b063bd5fc
</p>
<p>
Author: Ichthyostega &lt;prg@ichthyostega.de&gt;
</p>
<p>
Date:&#160;&#160;&#160;Tue Nov 7 18:37:20 2023 +0100
</p>
<p>
</p>
<p>
&#160;&#160;&#160;&#160;Scheduler: integrate sanity check on timings
</p>
<p>
&#160;&#160;&#160;
</p>
<p>
&#160;&#160;&#160;&#160;...especially to prevent a deadline way too far into the future,
</p>
<p>
&#160;&#160;&#160;&#160;since this would provoke the BlockFlow (epoch based) memory manager
</p>
<p>
&#160;&#160;&#160;&#160;to run out of space.
</p>
<p>
&#160;&#160;&#160;
</p>
<p>
&#160;&#160;&#160;&#160;Just based on gut feeling, I am now imposing a limit of 20seconds,
</p>
<p>
&#160;&#160;&#160;&#160;which, given current parametrisation, with a minimum spacing of 6.6ms
</p>
<p>
&#160;&#160;&#160;&#160;and 500 Activities per Block would at maximum require 360 MiB for
</p>
<p>
&#160;&#160;&#160;&#160;the Activities, or 3000 Blocks. With *that much* blocks, the
</p>
<p>
&#160;&#160;&#160;&#160;linear search would degrade horribly anyway...
</p>
</body>
</html></richcontent>
<icon BUILTIN="info"/>
</node>
<node CREATED="1703166931888" ID="ID_1152423629" MODIFIED="1703166955138" TEXT="Abstand zur Deadline dort auf 20sec in die Zukunft begrenzt"/>
<node CREATED="1703166958757" ID="ID_1813975073" MODIFIED="1703166991509" TEXT="Begr&#xfc;ndung: das sind 3000 Blocks mit aktuellen Parametern &#x27f9; 360MiB"/>
<node CREATED="1703167028300" ID="ID_166453307" MODIFIED="1703167277005" TEXT="Zusammenhang war damals: Deadline-Angabe verpflichtend einf&#xfc;hren">
<arrowlink COLOR="#2f4758" DESTINATION="ID_169718532" ENDARROW="Default" ENDINCLINATION="454;1825;" ID="Arrow_ID_309449594" STARTARROW="None" STARTINCLINATION="-750;-32;"/>
<node CREATED="1703167043250" ID="ID_1186036244" MODIFIED="1703167064427">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
der sanityCheck pr&#252;ft also vornehmlich <b>da&#223; es eine Deadline gibt</b>
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1703167108644" ID="ID_115218489" MODIFIED="1703167128274" TEXT="bei der Gelegenheit habe ich auch eine Entfernungs-Begrenzung eingef&#xfc;hrt"/>
<node CREATED="1703167729446" ID="ID_1652334689" MODIFIED="1703167755775" TEXT="und auch schon &#xfc;berlegt, ob man hier mit dem BlockFlow kommunizieren sollte"/>
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1703167756723" ID="ID_1704984903" LINK="#ID_1475597715" MODIFIED="1703168328783" TEXT="...das aber dann vertagt (weil nicht so ganz trivial)">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
...dazu m&#252;&#223;te n&#228;mlich der BlockFlow viel dynamischer seine Config auswerten &#8212; l&#228;stiges Thema &#8212; YAGNI
</p>
</body>
</html></richcontent>
<icon BUILTIN="hourglass"/>
</node>
</node>
<node COLOR="#435e98" CREATED="1703169088376" ID="ID_1123454190" MODIFIED="1703181202411" TEXT="was kann ein sanityCheck pr&#xfc;fen, und wo?">
<icon BUILTIN="forward"/>
<node COLOR="#338800" CREATED="1703169105622" ID="ID_1898885849" MODIFIED="1703181209674" TEXT="der low-level Allokator k&#xf6;nnte eine Obergrenze setzen">
<icon BUILTIN="yes"/>
<node CREATED="1703181033436" ID="ID_608144195" MODIFIED="1703181229745">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
w&#228;hle hier <b>8 GiB</b>&#160;f&#252;r die totale Allokation
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1703181048241" ID="ID_1736906659" MODIFIED="1703181077774" TEXT="das ist relativ beliebig &#x2014; aber f&#xe4;ngt schon mal Irrsinns-Werte ab"/>
</node>
<node COLOR="#338800" CREATED="1703169121788" ID="ID_1453938847" MODIFIED="1703181209669" TEXT="der BlockFlow k&#xf6;nnte zu gro&#xdf;e Schritte begrenzen">
<icon BUILTIN="yes"/>
<node CREATED="1703181080549" ID="ID_1889822736" MODIFIED="1703181239440">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
begrenze hier konsistent mit dem Scheduler auf <b>+3000</b>&#160;neue Bl&#246;cke pro Schritt
</p>
</body>
</html></richcontent>
</node>
<node CREATED="1703181103210" ID="ID_1352724835" MODIFIED="1703181194583" TEXT="effektiv ist daher die Limitierung im Scheduler wesentlich strenger">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
weil das Limit im BlockFlow-Allokator nur greift, wenn wir <b>tats&#228;chlich</b>&#160; auf Minimal-Blockggr&#246;&#223;e unten sind, w&#228;hrend der Scheduler eine <b>feste Obergrenze</b>&#160;f&#252;r die Deadlines erzwingt.
</p>
</body>
</html></richcontent>
</node>
</node>
</node>
<node COLOR="#338800" CREATED="1703181256182" ID="ID_97506666" MODIFIED="1703181269712" TEXT="verifiziert: beide Limits w&#xfc;rden in unserem Beispielfall triggern">
<icon BUILTIN="button_ok"/>
</node>
</node>
</node>
<node COLOR="#338800" CREATED="1703182904946" ID="ID_1556068867" MODIFIED="1703182960627" TEXT="Test l&#xe4;uft">
<icon BUILTIN="button_ok"/>
<node BACKGROUND_COLOR="#f8c4cd" CREATED="1703182931454" HGAP="38" ID="ID_466017214" MODIFIED="1703183020926" STYLE="bubble" VSHIFT="16">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
und ist jetzt sogar <b>schenller</b>&#160;als der single-threaded Fall
</p>
</body>
</html></richcontent>
<edge COLOR="#f13f5e"/>
</node>
</node>
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1703182827109" HGAP="-1" ID="ID_538328256" MODIFIED="1703183034620" TEXT="was so wos ausmacha ko" VSHIFT="3">
<font NAME="SansSerif" SIZE="10"/>
<icon BUILTIN="ksmiletris"/>
</node>
</node>
<node CREATED="1703185430737" ID="ID_1494826249" MODIFIED="1703185960530" TEXT="weitere Beobachtungen">
<icon BUILTIN="idea"/>
<node CREATED="1703185450863" ID="ID_592897039" MODIFIED="1703185457962" TEXT="sp&#xe4;terer Planungs-Chunk">
<node CREATED="1703185459030" ID="ID_158923665" MODIFIED="1703185583729" TEXT="andere Worker arbeiten noch parallel"/>
<node CREATED="1703185473187" ID="ID_122559529" MODIFIED="1703185500034" TEXT="dann f&#xfc;r 400&#xb5;s eine Contention-Phase mit Verz&#xf6;gerung feststellbar"/>
<node CREATED="1703185500836" ID="ID_1723892087" MODIFIED="1703185521889" TEXT="nach Ende des Planungs-Chunk sind nach 300&#xb5;s bereits wieder 4 Nodes parallel am Arbeiten"/>
</node>
<node CREATED="1703185525277" ID="ID_1186537034" MODIFIED="1703185548805" TEXT="die gesamte WorkForce arbeitet nun an dem &#xbb;Knoten&#xab;"/>
<node CREATED="1703185551649" ID="ID_1991806921" MODIFIED="1703185608701" TEXT="sobald mehrere Nodes lange brauchen, r&#xe4;umt ein Worker das ganze sonstige Schedule ab"/>
<node CREATED="1703185615217" ID="ID_545979366" MODIFIED="1703185638129" TEXT="wenn die Nodes aber Folge-Jobs &#xbb;abwerfen&#xab; konzentriert sich die WorkForce darauf"/>
<node CREATED="1703185643605" ID="ID_1805994004" MODIFIED="1703185663367" TEXT="ABER: wenn das restliche Schedule bereits leer geworden ist...">
<icon BUILTIN="forward"/>
<node CREATED="1703185664690" ID="ID_98657162" MODIFIED="1703185676116" TEXT="dann reduziert sich schrittweise die aktive Kapazit&#xe4;t"/>
<node CREATED="1703185676824" ID="ID_14362696" MODIFIED="1703185693000" TEXT="und zwar auf das Ma&#xdf; was an Folge-Jobs im Schnitt in der Queue ist"/>
<node CREATED="1703185695734" ID="ID_1429825370" MODIFIED="1703185712917" TEXT="wer da nichts mehr bekommt, wird auf die n&#xe4;chsten 20ms verteilt und &#xbb;verschwindet&#xab; dann"/>
<node CREATED="1703185719407" ID="ID_889140960" MODIFIED="1703185732130" TEXT="so pa&#xdf;t sich der Rest der durchschnittligen Parallelit&#xe4;t an"/>
</node>
</node>
</node>
</node>
@ -112950,6 +113513,57 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</html></richcontent>
</node>
</node>
<node CREATED="1703175606961" ID="ID_977524589" MODIFIED="1703176863414" TEXT="Number Conversions">
<node CREATED="1703175642069" ID="ID_1436256174" LINK="https://en.cppreference.com/w/cpp/language/implicit_conversion#Integral_promotion" MODIFIED="1703175661949" TEXT="Implicit Conversions in expression evaluation">
<node CREATED="1703175682088" ID="ID_1645952636" MODIFIED="1703175704352" TEXT="narrow values will be widened to int/uint"/>
<node CREATED="1703175784081" FOLDED="true" ID="ID_1915244657" MODIFIED="1703176874574" TEXT="Promotions happen automatically and are value preserving">
<node CREATED="1703176055148" ID="ID_559291421" MODIFIED="1703176060408" TEXT="Integral Promotons">
<node CREATED="1703176149752" ID="ID_171090702" MODIFIED="1703176158899" TEXT="ordered list of candiate types"/>
<node CREATED="1703176159394" ID="ID_1603702397" MODIFIED="1703176171857" TEXT="the first one is used that can represent the value unaltered"/>
<node CREATED="1703176173021" ID="ID_1929827887" MODIFIED="1703176212236" TEXT="int, uint, long, ulong, long long, unsigned long long, &lt;original type&gt;"/>
</node>
<node CREATED="1703176068811" ID="ID_1500011190" MODIFIED="1703176076590" TEXT="Floatingpoint Promotion">
<node CREATED="1703176077578" ID="ID_1186257475" MODIFIED="1703176087845" TEXT="float -&gt; double">
<node CREATED="1703176089790" ID="ID_415497773" MODIFIED="1703176092420" TEXT="value preserving"/>
<node CREATED="1703176092768" ID="ID_468819434" MODIFIED="1703176098483" TEXT="same mantissa, same exponent"/>
</node>
</node>
</node>
<node CREATED="1703176401791" FOLDED="true" ID="ID_325823218" MODIFIED="1703176899184" TEXT="Result value of expression">
<linktarget COLOR="#7da0ba" DESTINATION="ID_325823218" ENDARROW="Default" ENDINCLINATION="-881;88;" ID="Arrow_ID_420115024" SOURCE="ID_468031830" STARTARROW="None" STARTINCLINATION="-1677;171;"/>
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1703176419317" ID="ID_1657935885" LINK="https://en.cppreference.com/w/cpp/language/usual_arithmetic_conversions#Integer_conversion_rank" MODIFIED="1703176456448" TEXT="operands of binary operators undergo Arithmetic Conversion"/>
<node CREATED="1703176457316" ID="ID_1093968313" MODIFIED="1703176571619" TEXT="Note: Integer Conversion Rank">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
the corresponding unsigned type has the <b>same rank </b>
</p>
</body>
</html></richcontent>
<node CREATED="1703176509054" MODIFIED="1703176509054" TEXT="long long"/>
<node CREATED="1703176509054" ID="ID_1436028783" MODIFIED="1703176509054" TEXT="long"/>
<node CREATED="1703176509054" MODIFIED="1703176509054" TEXT="int"/>
<node CREATED="1703176509054" MODIFIED="1703176509054" TEXT="short"/>
<node CREATED="1703176509054" MODIFIED="1703176509054" TEXT="signed char"/>
</node>
<node CREATED="1703176579144" ID="ID_328120141" MODIFIED="1703176590331" TEXT="can combine unsigned and signed of same rank">
<icon BUILTIN="messagebox_warning"/>
<node CREATED="1703176655486" ID="ID_502422957" MODIFIED="1703176666294" TEXT="U &lt;op&gt; S"/>
<node CREATED="1703176667236" ID="ID_660752908" MODIFIED="1703176717920" TEXT="rank(U) &gt;= rank(S) &#x27fc; res U">
<icon BUILTIN="messagebox_warning"/>
</node>
<node CREATED="1703176700886" ID="ID_1588687894" MODIFIED="1703176723835" TEXT="rank(U) &lt; rank(S) &#x27fc; res S">
<icon BUILTIN="button_ok"/>
</node>
</node>
</node>
<node CREATED="1703176027969" ID="ID_434248727" MODIFIED="1703176047234" TEXT="Conversions happen at asignment or force-conversion and can alter the value"/>
</node>
</node>
<node CREATED="1620405445951" ID="ID_1127258714" MODIFIED="1620405460977" TEXT="&#xbb;perfect forwarding&#xab;">
<node CREATED="1620405462300" ID="ID_1712821553" MODIFIED="1620405478341" TEXT="hatte nun mehrfach Probleme in Kombination mit Variadic-Templates"/>
<node CREATED="1620405479689" ID="ID_53418276" MODIFIED="1620405514581" TEXT="std::forward&lt;ARGS&gt;(args) ... ">