Library: draft standard case for actual memory allocation

- attempt to use the minimal possible storage for the management itself
- rely on the `std::align()` function to do the actual placement
This commit is contained in:
Fischlurch 2024-05-15 23:46:37 +02:00
parent eeda3aaa56
commit c623298ac8
2 changed files with 101 additions and 78 deletions

View file

@ -44,19 +44,16 @@
#include "lib/error.hpp"
#include "lib/nocopy.hpp"
#include "lib/sync-classlock.hpp"
#include "lib/scoped-holder.hpp"
#include "lib/scoped-holder-transfer.hpp"
#include <utility>
#include <vector>
#include <utility> ///////////////////OOO woot?
#include <memory>
namespace lib {
/**
/**
* A pile of objects sharing common allocation and lifecycle.
* AllocationCluster owns a number of object families of various types.
* Each of those contains a initially undetermined (but rather large)
@ -100,6 +97,10 @@ namespace lib {
AllocationCluster* mother_;
};
/* maintaining the Allocation */
void* storage_;
size_t remain_;
public:
AllocationCluster ();
~AllocationCluster () noexcept;
@ -109,7 +110,7 @@ namespace lib {
TY&
create (ARGS&& ...args)
{
return * new(allotMemory (sizeof(TY))) TY (std::forward<ARGS> (args)...);
return * new(allot<TY>()) TY (std::forward<ARGS> (args)...);
}
template<typename X>
@ -141,16 +142,20 @@ namespace lib {
* possibly claiming a new pool block.
*/
void*
allotMemory (size_t bytes)
allotMemory (size_t bytes, size_t alignment)
{
void* loc = std::align(alignment, bytes, storage_, remain_);
if (loc)
return loc;
UNIMPLEMENTED ("actual memory management");
///////////////////////////////////////////////////////////OOO claim next macro block
}
template<typename X>
X*
allot (size_t cnt =1)
{
return static_cast<X*> (allotMemory (cnt * sizeof(X)));
return static_cast<X*> (allotMemory (cnt * sizeof(X), alignof(X)));
}
};

View file

@ -80694,8 +80694,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
An der Stelle habe ich nicht weiter analysiert, sondern einfach Heap-Allokationen gemacht; der Grund seinerzeit war, da&#223; Christian den &#187;Mempool&#171; &#252;berall einf&#252;hren wollte &#8212; ein Ansatz, den ich grunds&#228;tzlich unterst&#252;tzte, wenngleich auch seine Implementierung zu einfach war, und ich damit diesen use-Case nicht sauber realisieren konnte. Damit unterblieben aber weitere &#220;berlegungen zum Allocation-Trend
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node CREATED="1715625485709" ID="ID_323773842" MODIFIED="1715625503477" TEXT="zu viel Locking &#x2014; und m&#xf6;glicherweise an der falschen Stelle"/>
<node CREATED="1715625511889" HGAP="39" ID="ID_1920622182" MODIFIED="1715625840520" TEXT="Effizienz der Familien-Pools erscheint fragw&#xfc;rdig" VSHIFT="-29">
@ -80708,8 +80707,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
damals hatte ich als Vorbild den <i>small-objects pool allocator </i>von Alexandrescu im Kopf; deshalb habe ich auch &#187;Familien&#171; von Objekten vorgesehen &#8212; ohne jedoch zu kl&#228;ren, ob und wie sich daraus ein Amortisierungs-Effekt ergibt. Nach gr&#252;ndlicherer &#220;berlegung erscheint mir das als ein Widerspruch im Konzept, denn diese small-objects-Pools laufen ja auf ein Tiling mit fortlaufend stattfindedenden Allokationen hinaus; das ist exakt das Gegenteil von dem, was mir hier vorschwebt. Damit w&#252;rden die Einzelpools nur Administrations-Overhead verursachen, der seine Vorteile &#252;berhaupt nicht ausspielen kann; stattdessen sollte besser in Betracht gezogen werden, alles heterogen, so wie es kommt, in gr&#246;&#223;ere Bl&#246;cke zu packen. Das Tiling w&#252;rde damit auf einem gr&#246;&#223;eren Level stattfinden, und w&#228;re in den Basis-Allocator verlagert...
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
</node>
<node CREATED="1714870490954" ID="ID_433835630" MODIFIED="1714870505595" TEXT="Aufr&#xe4;umen">
@ -80999,8 +80997,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
&#10233; Konsequenz: zus&#228;tzlicher Template-Parameter f&#252;r das<i>&#160;Spacing</i>
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node COLOR="#5b280f" CREATED="1715532386464" ID="ID_1896451330" MODIFIED="1715532398219" TEXT="oder eben eine VTable wie in RefArray">
<icon BUILTIN="button_cancel"/>
@ -81064,8 +81061,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
oder man bekommt eine<i>&#160;implizite Runtime</i>
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
</node>
</node>
@ -81087,8 +81083,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
wenn die Daten &#8222;woanders&#8220; liegen
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node CREATED="1715533317000" ID="ID_252143573" MODIFIED="1715533493572">
<richcontent TYPE="NODE"><html>
@ -81100,8 +81095,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
&#10233; das <b>Allocator-Problem</b>&#160;&#252;bertr&#228;gt sich <b>komplett</b>&#160; auf den Container selber
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<richcontent TYPE="NOTE"><html>
<head>
@ -81111,8 +81105,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
warum? weil man dann zwingend im Container selber einen &#187;Slot&#171; mit einem Functor oder Allocator-Pointer rumschleppt &#8212; oder doch wieder einen zus&#228;tzlichen Instanz-Typ-Tag
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
</node>
</node>
@ -81144,8 +81137,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
&#10233; bl&#228;ht die Storage um 30% auf
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node CREATED="1715618955861" ID="ID_189897298" MODIFIED="1715619378057" TEXT="dann halt doch blo&#xdf; Heap-Allokationen machen">
<richcontent TYPE="NOTE"><html>
@ -81168,8 +81160,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</li>
</ul>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node CREATED="1715620143727" ID="ID_828708828" MODIFIED="1715620159863" TEXT="Zugriff auf den Allocator per DI (statisch) oder Thread-local"/>
<node CREATED="1715620242056" ID="ID_427769562" MODIFIED="1715620649844" TEXT="Spezieller Allocator mit Block-de-Allocation">
@ -81182,8 +81173,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
...man verwendet <i>nur speziell im produktiven Einsatz im Node-Graph</i>&#160; einen besonderen Allocator, der zwar den Destruktor aufruf, aber den Speicher nicht freigibt; alloziert wird immer in einen kompakten Block hinein, der dann auf der Basis der Proze&#223;-Kenntnis als Ganzes verworfen und neu verwendet wird.
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<icon BUILTIN="forward"/>
</node>
</node>
@ -81203,8 +81193,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
...weil std::vector zwar bereits alles bietet, aber eingebettet in sehr komplexen Code &#8212; im Besonderen d&#252;rfte es schwierig werden, das Thema on-demand-growth vs non-copyable zu umschiffen
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
</node>
<node CREATED="1715624963026" ID="ID_744219090" MODIFIED="1715624972411" TEXT="separaten Builder f&#xfc;r die zwei Nutz-Muster">
@ -81222,8 +81211,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
...das hei&#223;t, ich gehe mal davon aus, da&#223; ich mit einer einzigen, dedizierten Implementierung erst mal den aktuellen Bedarf decken kann; daraus k&#246;nnte allerdings sp&#228;ter immer noch ein Concept gemacht werden, welches dann alternativ auch durch ScopedCollection oder durch eine embedded-storage-L&#246;sung erf&#252;llt werden kann.
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
</node>
</node>
@ -81242,8 +81230,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
heterogene Allokation in eine Sequenz gr&#246;&#223;erer Bl&#246;cke; keinerlei de-Allokation und kein Locking
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node CREATED="1715625881800" ID="ID_1460908503" MODIFIED="1715626254822" TEXT="man k&#xf6;nnte aber die bestehende Impl. erst mal ungesehen verwenden">
<richcontent TYPE="NOTE"><html>
@ -81269,8 +81256,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</li>
</ul>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node CREATED="1715625901869" ID="ID_460237769" MODIFIED="1715626344549" TEXT="oder aber gleich ganz liegen lassen und blo&#xdf; Heap-Allokationen machen">
<richcontent TYPE="NOTE"><html>
@ -81282,8 +81268,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
...<i>wenn man schon </i>die bestehenden Implementierung nutzt (wohl wissend, da&#223; ihre inh&#228;renten Probleme erst mal nicht relevant sind), dann kann man genausogut <i>ganz auf bl&#246;d </i>sich auf den KISS-Standpunkt stellen und einfach Heap-Allokationen machen, denn die sind heutzutage verdammt effizient geworden
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node CREATED="1715625929114" ID="ID_704028431" MODIFIED="1715625953412">
<richcontent TYPE="NODE"><html>
@ -81295,8 +81280,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
...und alles das l&#228;uft auf weitere <b>technische Schulden</b>&#160;hinaus
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
</node>
<node CREATED="1715626381670" ID="ID_365556330" MODIFIED="1715626396019" TEXT="Idee: den Allocation-Cluster unter gleichem Namen im Grund neu schreiben">
@ -81312,8 +81296,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
...die allesamt mit dem Model + Player zu tun haben; einzige externe Verkoppelung ist der LinkedElements_test, und auch dieser stellt explizit einen Vorgriff auf die Verwendung im low-level-Model dar.
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node CREATED="1715626599088" ID="ID_1068758723" MODIFIED="1715626653670" TEXT="das API ist schmal und k&#xf6;nnte inkrementell umgestaltet werden">
<richcontent TYPE="NOTE"><html>
@ -81325,8 +81308,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
...da der davon abh&#228;ngende Code <i>effektiv nur compilierbar ist, aber nicht lauff&#228;hig</i>
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node CREATED="1715626710965" ID="ID_1722763351" MODIFIED="1715626721940" TEXT="die neue L&#xf6;sung w&#xe4;re in jedem Fall einfacher">
<node CREATED="1715626738174" ID="ID_714358898" MODIFIED="1715626997202" TEXT="alles Locking f&#xe4;llt weg"/>
@ -81341,8 +81323,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
let it crash &#8212; wenn tats&#228;chlich eine Exception fliegt, ist es ziemlich wahrscheinlich, da&#223; der ganze Cluster sowiso weggeworfen wird; wenn nicht, dann akzeptieren wir einfach toten Speicher.
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node CREATED="1715626853846" ID="ID_540898270" MODIFIED="1715626985387">
<richcontent TYPE="NODE"><html>
@ -81354,8 +81335,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
die Bedeutung ist <b>geringer geworden</b>
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<richcontent TYPE="NOTE"><html>
<head>
@ -81365,8 +81345,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
seinerzeit habe ich im AllocationCluster etwas gesehen, da&#223; pervasiv &#252;berall im Code verwendet wird, analog zum Mempool. Inzwischen stehe ich auf dem Standpunkt, da&#223; f&#252;r die meisten Allokationen der Standard-Heap-Allokator sowiso gut genug ist (oder man nutzt ohnehin den Stack oder eine statische Variable); spezielle Allokatoren sind nach meinem heutigen Verst&#228;ndnis nur noch sinnvoll, wenn sie extrem spezifisch sind
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
</node>
</node>
@ -81382,8 +81361,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
...oder zumindest k&#246;nnte man ein limitiertes Teil-Konzept umsetzen; mir f&#228;llt auf, da&#223; diverse Methoden im Standard-Allocator inzwischen durch Traits ersetzt wurden.
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<node CREATED="1715725369201" ID="ID_1600204256" MODIFIED="1715725381650" TEXT="tats&#xe4;chlich ist es heutzutage sehr einfach"/>
<node CREATED="1715725400796" ID="ID_1894647974" MODIFIED="1715725416576" TEXT="praktisch jeder custom-allocator kann standardkonform gemacht werden">
<icon BUILTIN="idea"/>
@ -81703,8 +81681,60 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<icon BUILTIN="flag-yellow"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1715725837111" ID="ID_1956366876" MODIFIED="1715725864907" TEXT="Basis-Allocator vorsehen">
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1715725837111" ID="ID_1956366876" MODIFIED="1715818720819" TEXT="Basis-Allocation vorsehen">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#435e98" CREATED="1715817001701" ID="ID_315311831" MODIFIED="1715817053842" TEXT="wie einbinden?">
<node COLOR="#5b280f" CREATED="1715817015550" ID="ID_116856376" MODIFIED="1715817030369" TEXT="als Standard-Allocator">
<icon BUILTIN="button_cancel"/>
</node>
<node CREATED="1715817031505" ID="ID_892440156" MODIFIED="1715817051313" TEXT="weiterhin als feste Implementierungs-Entscheidung">
<icon BUILTIN="forward"/>
<node CREATED="1715817058766" ID="ID_1820924124" MODIFIED="1715817078576" TEXT="AllocationCluster ist keine generische Library-Klasse"/>
<node CREATED="1715817079155" ID="ID_395981478" MODIFIED="1715817088157" TEXT="sondern eine sehr speziell gebundene Einrichtung"/>
<node CREATED="1715817092113" ID="ID_1132434919" MODIFIED="1715817104459" TEXT="ein generischer Allocator w&#xfc;rde in den Typ eingehen"/>
<node CREATED="1715817106468" ID="ID_1098144156" MODIFIED="1715817115970" TEXT="...und das ist nur unn&#xf6;tige Komplikation"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1715818949821" ID="ID_1747630681" MODIFIED="1715818962407" TEXT="Thema: Alignment">
<icon BUILTIN="flag-yellow"/>
<node CREATED="1715818964036" ID="ID_1917864530" MODIFIED="1715818999461" TEXT="bedeutet: der Offset wird justiert bis er auf einer Alignment-Grenze liegt"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1715819022774" ID="ID_541145684" MODIFIED="1715819026470" TEXT="Anforderungen">
<icon BUILTIN="flag-yellow"/>
<node CREATED="1715819037772" ID="ID_1987233619" MODIFIED="1715819050902" TEXT="soll selber mit dem absoluten Minimum an Storage auskommen"/>
<node CREATED="1715819058921" ID="ID_895637699" MODIFIED="1715819099232" TEXT="mu&#xdf; zur de-Allokation eine Basis-Block-Kette navigieren"/>
<node CREATED="1715819206460" ID="ID_897739837" MODIFIED="1715819231318" TEXT="mu&#xdf; jedweils im aktuellen Block den Rest-Speicher feststellen k&#xf6;nnen"/>
<node CREATED="1715819263910" ID="ID_1512700101" MODIFIED="1715819291686" TEXT="soll idealerweise auch noch die Destructor-Closures mit unterbringen"/>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1715819352242" ID="ID_1754180627" MODIFIED="1715820238650" TEXT="Implementierung">
<icon BUILTIN="pencil"/>
<node CREATED="1715820246484" ID="ID_232038748" MODIFIED="1715820255249" TEXT="Idee / Skizze">
<icon BUILTIN="idea"/>
<node CREATED="1715819500198" ID="ID_210469417" MODIFIED="1715819513137" TEXT="ein Paar (next*, remaining_size)">
<node CREATED="1715819811133" ID="ID_1658998228" LINK="https://en.cppreference.com/w/cpp/memory/align" MODIFIED="1715819832631" TEXT="damit kann man die std::align()-Funktion verwenden">
<icon BUILTIN="idea"/>
</node>
</node>
<node CREATED="1715819526899" ID="ID_53500032" MODIFIED="1715819535331" TEXT="am Anfang jeden Blocks">
<node CREATED="1715819536259" ID="ID_1810416594" MODIFIED="1715819553483" TEXT="pred* zum Vorg&#xe4;nger"/>
<node CREATED="1715819554882" ID="ID_153472378" MODIFIED="1715819569288" TEXT="ein LinkedElements f&#xfc;r die Destruktoren"/>
</node>
<node CREATED="1715819574814" ID="ID_1318382076" MODIFIED="1715819613401" TEXT="via next + remaining_size + Blockgr&#xf6;&#xdf;e findet man den Block-Anfang"/>
<node CREATED="1715819629757" ID="ID_1012373659" MODIFIED="1715819639488" TEXT="damit kann man vom letzten Block aus r&#xfc;ckw&#xe4;rts aufrollen"/>
</node>
<node COLOR="#338800" CREATED="1715820275925" ID="ID_1184193638" MODIFIED="1715820287810" TEXT="Standardfall: Speicher belegen">
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1715820259913" ID="ID_13842300" MODIFIED="1715820269104" TEXT="Check f&#xfc;r zu gro&#xdf;e Objekte">
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1715820289221" ID="ID_1541316374" MODIFIED="1715820300780" TEXT="&#xdc;berlauf: neuen Block belegen">
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1715820305436" ID="ID_1741026762" MODIFIED="1715820308396" TEXT="Clean-up">
<icon BUILTIN="flag-yellow"/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1715790315814" ID="ID_878890004" MODIFIED="1715790393998" TEXT="L&#xf6;sung f&#xfc;r die Destruktoren schaffen">
<linktarget COLOR="#af578d" DESTINATION="ID_878890004" ENDARROW="Default" ENDINCLINATION="-446;33;" ID="Arrow_ID_464677545" SOURCE="ID_412040509" STARTARROW="None" STARTINCLINATION="-568;-24;"/>
@ -81730,8 +81760,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
Der Beschlu&#223; zur L&#246;sung sieht vor, diese Belange <i>markierbar </i>zu machen, um dann sp&#228;ter differenziert handeln zu k&#246;nnen.
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<icon BUILTIN="idea"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1715790540241" ID="ID_698638121" MODIFIED="1715795875494" TEXT="Registry f&#xfc;r clean-up-Aktionen direkt im Cluster verankern">
@ -81747,8 +81776,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
...somit kann auf Basis der einzelnen, konkreten Datenstruktur entschieden (und sp&#228;ter auch korrigiert) werden, ob ein expliziter clean-up-Aufruf notwendig ist; f&#252;r die einzelne Datenstruktur d&#252;rfte das lokal jeweils klar entscheidbar sein, und ich erwarte, da&#223; durch die Anbindung an den Allocation-Cluster diese Entscheidungsm&#246;glichkeit auch langfristig klar dokumentiert ist &#8212; und zwar sollte das von &#252;blichen C++ Praktiken abweichende Verhalten auch als der Spezialfall dargestellt sein (wenngleich auch erwartet wird, da&#223; die meisten Datenstrukturen von diesem Spezialfall gebrauch machen)
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<node CREATED="1715790777543" ID="ID_953637060" MODIFIED="1715790789971" TEXT="create &#x27f9; Destruktor wird aufgerufen"/>
<node CREATED="1715790790703" ID="ID_578796550" MODIFIED="1715790803259" TEXT="createDisposable &#x27f9; Destruktor wird nicht aufgerufen"/>
</node>
@ -81962,8 +81990,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
Kurzfristig erscheint das als eine naheliegende Optimierung, die einem praktisch &#187;in den Scho&#223; f&#228;llt&#171; (die Implementierung wird dadurch sogar drastisch einfacher). Aber l&#228;ngerfristig bef&#252;rchte ich eine heimt&#252;cksiche Gefahr, denn die hier genommene Abk&#252;rzung kann leicht &#252;bersehen werden, da sie den &#252;blichen Gepflogenheiten zuwiderl&#228;uft. Im Lauf der Zeit k&#246;nnen sich so Speicher- und Ressourcen-Lecks einschleichen, die dann nur mit erheblichem und fokussiertem Aufwand aufzur&#228;umen sind
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node CREATED="1715786638937" ID="ID_220404719" MODIFIED="1715787515314" TEXT="C++ Basis-Kontrakt: Determinismus">
<richcontent TYPE="NOTE"><html>
@ -81975,8 +82002,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
Es handelt sich um eines der markanten Eigenschaften der Sprache C++ : Kontrolle und Determinismus bis ins kleinste Detail &#8212; und das pr&#228;gt den allt&#228;glichen Stil der Arbeit; weithin kann man sich auf Abstraktionen verlassen, weil diese sich wiederum auf Abstraktionen verlassen k&#246;nnen; wenn alles genau und zuverl&#228;ssig ist, dann werden auch weitreichende Aktionen planbar und handhabbar.
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node CREATED="1715787292122" ID="ID_882850258" MODIFIED="1715787964678" TEXT="es ist ein weit-reichendes Subsystem">
<richcontent TYPE="NOTE"><html>
@ -81988,8 +82014,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
Hier geht es um das gesamte low-level-Model, sowie m&#246;glicherweise Teile des Build-Prozesses und des Regelwerks, die daran angekn&#252;pft sein k&#246;nnten &#8212; und das bedeutet, mit einer (wie es zun&#228;chst scheint) sehr lokalen und tief verborgenen Optimierung k&#246;nnte der Grund-Kontrakt in einem erheblichen Teil der Applikation ge&#228;ndert werden
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
</node>
<node CREATED="1715786776566" ID="ID_1885525073" MODIFIED="1715786778242" TEXT="contra">
@ -82003,8 +82028,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
Der Aufwand, der allein f&#252;r das Aufrufen der aller Destruktoren getrieben werden mu&#223;, ist nicht unerheblich, denn f&#252;r jeden Typ mu&#223; eine Closure im Datensegment erzeugt werden und f&#252;r jede einzelne Allokation mu&#223; diese per Funktionszeiger aufrufbar sein; au&#223;erdem mu&#223; die gesamte Allokation navigierbar gemacht werden &#8212; also zwei &#187;Slots&#171; zus&#228;tzlich f&#252;r jede einzelne Allokation. Das ist sehr viel f&#252;r eine Datenstruktur, die aus vielen kleinen und sehr flexiblen Descriptor-Elementen bestehen wird; die meisten Nodes haben erwartungsgem&#228;&#223; nur einen Eingang und einen Ausgang, was bedeutet, da&#223; f&#252;r jeweils nur eine einzige ID (ein &#187;Slot&#171;) zus&#228;tzlich ein Container (2 &#187;Slot&#171;) und dann noch 4 &#187;Slot&#171; Allokations-Overhead notwendig sind.
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node CREATED="1715786779246" ID="ID_1339652048" MODIFIED="1715788973479">
<richcontent TYPE="NODE"><html>
@ -82016,8 +82040,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
in der Regel sind es<i>&#160;cold pages</i>
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<richcontent TYPE="NOTE"><html>
<head>
@ -82027,8 +82050,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
Aus Performance-Sicht besonders fatal ist, da&#223; zum Zeitpunkt der Bulk-de-Allokation mit hoher Wahrscheinlichkeit alle betroffenen memory pages bereits &#187;cold&#171; sind, d.h. aus dem Cache herausgefallen; wir m&#252;ssen also eine Menge von Speicherseiten &#252;ber den Bus ziehen, blo&#223; um sie zu navigieren und dann...
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node CREATED="1715786817201" ID="ID_1883341443" MODIFIED="1715789112354" TEXT="90% der F&#xe4;lle brauchen keinen dtor-Aufruf">
<richcontent TYPE="NOTE"><html>
@ -82040,8 +82062,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
...in den allermeisten F&#228;llen n&#228;mlich<i>&#160;exakt gar nichts</i>&#160; zu tun. Dies unter der Annahme, da&#223; die Struktur gr&#246;&#223;tenteils selbst-referentiell ist; zwar werden dadurch reihenweise verkettete Destruktor-Aufrufe stattfinden, welche aber alle letztlich beim Allocator enden, welcher dann (ganz bewu&#223;t) nichts tut, weil der gesamte Speicherblock anschlie&#223;end ohnehin verworfen wird. Da es sich jedoch um dynamisch aufgebaute Datenstrukturen handelt, kann der Optimizer diesen Leerlauf nicht erkennen und beseitigen
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
<node CREATED="1715786961514" ID="ID_1214786701" MODIFIED="1715789369565" TEXT="es handelt sich um einer permanent-laufende Aktivit&#xe4;t">
<richcontent TYPE="NOTE"><html>
@ -82053,8 +82074,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
Es steht zu bef&#252;rchten, da&#223; w&#228;hrend der normalen Edit-T&#228;tigkeit alle par 1/10-sec ein Builder-Lauf getriggert wird &#8212; und ich sch&#228;tze, da&#223; ein erheblicher Anteil der tats&#228;chlichen Laufzeit in das Konstruieren der Datenstruktur geht, denn der zugrundeliegende trade-off ist ja grade<i>&#160; space-for-time.</i>&#160;Wenngleich auch der Neubau ebenfalls schlecht f&#252;r den Cache ist, so kann man doch zumindet in Teilen hoffen, da&#223; die neu gebauten Strukturen zumindest bis zur ersten Ber&#252;hrung durch den Play-Proze&#223; im L3 bleiben. F&#252;r die alten Strukturen gilt das aber nicht, sie stellen rein nutzlosen Balast dar.
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
</node>
<node CREATED="1715789372444" ID="ID_869337683" MODIFIED="1715789375047" TEXT="Diskussion">
@ -82071,8 +82091,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
Ich handle hier nur auf Basis eines Bauchgef&#252;hls, und alle Erfahrung zeigt, da&#223; man dabei meist die Gewichte falsch setzt.
</p>
</body>
</html>
</richcontent>
</html></richcontent>
<icon BUILTIN="messagebox_warning"/>
</node>
<node CREATED="1715789557219" ID="ID_1705458605" MODIFIED="1715789587814" TEXT="ein Aufweichen des Determinismus-Prinzips ist sp&#xe4;ter nicht mehr korrigierbar">
@ -82094,8 +82113,7 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
Angenommen, ich mache diese Optimierung jetzt <b>nicht</b>, bereite sie aber vor; sp&#228;ter dann zeigt sich (mit guter Wahrscheinlichkeit) tats&#228;chlich ein relevanter Overhead &#10233; dann ist der Druck zur Optimierung umso st&#228;rker, und man wird die vorbereitete Option &#187;ziehen&#171; und die weitreichenden Konsequenzen in Kauf nehmen, da die Behebung eines konkreten Problems immer alle strategischen und methodischen Erw&#228;gungen <b>&#252;bersteuert</b>. Das w&#228;re der schlechtest m&#246;gliche Verlauf, denn zu eine so sp&#228;ten Zeitpunkt kann man kaum mehr etwas tun, um eine weitreichende &#196;nderung der Konventionen abzufedern
</p>
</body>
</html>
</richcontent>
</html></richcontent>
</node>
</node>
</node>