Library: work out ramifications of the changed design

Notably this raises the difficult question,
whether to ensure **invocation of destructors**.

Not invoking dtors ''breaks one of the most fundamental contracts''
of the C++ language — yet the infrastructure to invoke dtors in such
a heterogeneous cluster of allocations creates a hugely significant
overhead and is bound to poison the caches (objects to be deallocated
typically sit in cold memory pages).

What makes this decision especially daunting is the fact that the
low-level-Model can be expected to be one of the largest systemic
data structures (letting aside the media buffers).

I am leaning towards a compromise: turn down this decision
towards the user of the `AllocationCluster`
This commit is contained in:
Fischlurch 2024-05-15 19:59:05 +02:00
parent fd49c68096
commit 13f51c910c
3 changed files with 337 additions and 125 deletions

View file

@ -127,6 +127,18 @@ namespace lib {
template<class TY>
size_t count() const;
size_t
numExtents() const
{
UNIMPLEMENTED ("Allocation management");
}
size_t
numBytes() const
{
UNIMPLEMENTED ("Allocation management");
}
private:
/**

View file

@ -28,24 +28,27 @@
#include "lib/test/run.hpp"
#include "lib/test/test-helper.hpp"
#include "lib/util.hpp"
#include "lib/util-foreach.hpp"
#include "lib/allocation-cluster.hpp"
#include "lib/scoped-holder.hpp"
#include "lib/test/diagnostic-output.hpp"/////////////////TODO
#include "lib/iter-explorer.hpp"
#include "lib/util.hpp"
#include <array>
#include <vector>
#include <limits>
#include <boost/lexical_cast.hpp>
#include <functional>
//#include <boost/lexical_cast.hpp>
using boost::lexical_cast;
//using boost::lexical_cast;
using lib::explore;
using lib::test::showSizeof;
using util::for_each;
using util::isnil;
using ::Test;
using std::numeric_limits;
using std::function;
using std::vector;
using std::array;
@ -54,94 +57,74 @@ namespace test {
namespace { // a family of test dummy classes
uint NUM_CLUSTERS = 5;
uint NUM_OBJECTS = 500;
uint NUM_FAMILIES = 5;
const uint NUM_CLUSTERS = 5;
const uint NUM_TYPES = 20;
const uint NUM_OBJECTS = 500;
long checksum = 0; // validate proper pairing of ctor/dtor calls
bool randomFailures = false;
template<uint i>
class Dummy
{
char content[i];
static_assert (0 < i);
array<uchar,i> content_;
public:
Dummy (char id=1)
Dummy (uchar id=1)
{
content[0] = id;
checksum += id;
}
Dummy (char i1, char i2, char i3=0)
{
char id = i1 + i2 + i3;
content[0] = id;
checksum += id;
if (randomFailures && 0 == (rand() % 20))
throw id;
content_.fill(id);
checksum += explore(content_).resultSum();
}
~Dummy()
~Dummy()
{
checksum -= content[0];
checksum -= explore(content_).resultSum();
}
char getID() { return content[0]; }
char getID() { return content_[0]; }
};
typedef ScopedHolder<AllocationCluster> PCluster;
typedef vector<PCluster> ClusterList;
inline char
truncChar (uint x)
{
return x % numeric_limits<char>::max();
}
template<uint i>
void
place_object (AllocationCluster& clu, uint id)
{
clu.create<Dummy<i>> (id);
}
place_object (AllocationCluster& clu, uchar id)
{
clu.create<Dummy<i>> (id);
}
typedef void (Invoker)(AllocationCluster&, uint);
Invoker* invoke[20] = { &place_object<1>
, &place_object<2>
, &place_object<3>
, &place_object<5>
, &place_object<10>
, &place_object<13>
, &place_object<14>
, &place_object<15>
, &place_object<16>
, &place_object<17>
, &place_object<18>
, &place_object<19>
, &place_object<20>
, &place_object<25>
, &place_object<30>
, &place_object<35>
, &place_object<40>
, &place_object<50>
, &place_object<100>
, &place_object<200>
};
inline array<function<void(AllocationCluster&, uchar)>, NUM_TYPES>
buildTrampoline()
{
return { place_object<1>
, place_object<2>
, place_object<3>
, place_object<5>
, place_object<10>
, place_object<13>
, place_object<14>
, place_object<15>
, place_object<16>
, place_object<17>
, place_object<18>
, place_object<19>
, place_object<20>
, place_object<25>
, place_object<30>
, place_object<35>
, place_object<40>
, place_object<50>
, place_object<100>
, place_object<200>
};
}
void
fillIt (PCluster& clu)
fill (AllocationCluster& clu)
{
clu.create();
if (20<NUM_FAMILIES)
NUM_FAMILIES = 20;
auto invoker = buildTrampoline();
for (uint i=0; i<NUM_OBJECTS; ++i)
{
char id = truncChar(i);
(*(invoke[rand() % NUM_FAMILIES])) (*clu,id);
}
invoker[rand() % NUM_TYPES] (clu, uchar(i));
}
}
@ -155,16 +138,11 @@ namespace test {
*/
class AllocationCluster_test : public Test
{
virtual void
run (Arg arg)
virtual void
run (Arg)
{
if (0 < arg.size()) NUM_CLUSTERS = lexical_cast<uint> (arg[0]);
if (1 < arg.size()) NUM_OBJECTS = lexical_cast<uint> (arg[1]);
if (2 < arg.size()) NUM_FAMILIES = lexical_cast<uint> (arg[2]);
simpleUsage();
checkAllocation();
checkErrorHandling();
checkLifecycle();
}
@ -173,68 +151,37 @@ namespace test {
{
AllocationCluster clu;
char c1(123), c2(56), c3(3), c4(4), c5(5);
Dummy<44>& ref1 = clu.create<Dummy<44>> ();
Dummy<37>& ref2 = clu.create<Dummy<37>> (c1);
Dummy<37>& ref3 = clu.create<Dummy<37>> (c2);
Dummy<1234>& rX = clu.create<Dummy<1234>> (c3,c4,c5);
char c1(123), c2(45);
Dummy<66>& ref1 = clu.create<Dummy<66>> ();
Dummy<77>& ref2 = clu.create<Dummy<77>> (c1);
Dummy<77>& ref3 = clu.create<Dummy<77>> (c2);
CHECK (&ref1);
CHECK (&ref2);
CHECK (&ref3);
CHECK (&rX);
TRACE (test, "%s", showSizeof(rX).c_str());
// TRACE (test, "%s", showSizeof(rX).c_str());///////////////////////OOO
//returned references actually point at the objects we created
CHECK (1 ==ref1.getID());
CHECK (123==ref2.getID());
CHECK (3+4+5==rX.getID());
// shows that the returned references actually
// point at the objects we created. Just use them
// and let them go. When clu goes out of scope,
// all created object's dtors will be invoked.
CHECK (45 ==ref3.getID());
CHECK (4 == clu.size());
CHECK (1 == clu.count<Dummy<44>>());
CHECK (2 == clu.count<Dummy<37>>());
CHECK (1 == clu.count<Dummy<1234>>());
CHECK (1 == clu.numExtents());
CHECK (66+77+77 == clu.numBytes());
// now use objects and just let them go;
}
void
checkAllocation()
checkLifecycle()
{
CHECK (0==checksum);
{
ClusterList clusters (NUM_CLUSTERS);
for_each (clusters, fillIt);
vector<AllocationCluster> clusters (NUM_CLUSTERS);
for (auto& clu : clusters)
fill(clu);
CHECK (0!=checksum);
}
CHECK (0==checksum);
}
void
checkErrorHandling()
{
CHECK (0==checksum);
{
randomFailures = true;
AllocationCluster clu;
for (uint i=0; i<NUM_OBJECTS; ++i)
try
{
char i1 = truncChar(i);
char i2 = truncChar(rand() % 5);
clu.create<Dummy<1>> (i1,i2);
}
catch (char id)
{
checksum -= id; // exception thrown from within constructor,
} // thus dtor won't be called. Repair the checksum!
}
randomFailures = false;
CHECK (0==checksum);
}
};
LAUNCHER (AllocationCluster_test, "unit common");

View file

@ -81679,11 +81679,99 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node CREATED="1715727255639" ID="ID_1782845675" MODIFIED="1715727439713" TEXT="allotMemory(size_t)"/>
</node>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1715782501810" ID="ID_455348105" MODIFIED="1715782506785" TEXT="Verwendungen anpassen">
<icon BUILTIN="pencil"/>
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1715782508685" ID="ID_524633561" MODIFIED="1715782536584" TEXT="AllocationCluster selber mu&#xdf; weiterhin default-constructible sein">
<icon BUILTIN="yes"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1715782580806" ID="ID_1223928211" MODIFIED="1715782592605" TEXT="tats&#xe4;chliche Objekt-Erzeugungen nachvollziehen...">
<icon BUILTIN="flag-yellow"/>
<node CREATED="1715782747520" ID="ID_1770179360" MODIFIED="1715782759542" TEXT="node-basic-test: OK"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1715782790810" ID="ID_1391251855" MODIFIED="1715782799529" TEXT="linked-elements-test: ">
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1715782815501" ID="ID_845459708" MODIFIED="1715782818814" TEXT="Nodefactory">
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1715782819622" ID="ID_232870110" MODIFIED="1715782823078" TEXT="Nodewiring">
<icon BUILTIN="flag-yellow"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1715782594292" ID="ID_1272598890" MODIFIED="1715782612650" TEXT="pr&#xfc;fen: keinerlei Multithreading">
<icon BUILTIN="flag-yellow"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1715725837111" ID="ID_1956366876" MODIFIED="1715725864907" TEXT="Basis-Allocator vorsehen">
<icon BUILTIN="flag-yellow"/>
</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;"/>
<icon BUILTIN="flag-yellow"/>
<node CREATED="1715790397014" ID="ID_14966020" MODIFIED="1715790537195" TEXT="Ergebnis einer Konfliktl&#xf6;sung">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
In diesem Konflikt stehen zwei gleicherma&#223;en bedeutsame Belange gegeneinander, ohne einen klaren Ansatz zur Entscheidung
</p>
<ul>
<li>
ein erhebliches Wartungs-Risiko
</li>
<li>
ein erheblicher Performance-Overhead
</li>
</ul>
<p>
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>
<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">
<icon BUILTIN="flag-yellow"/>
</node>
<node CREATED="1715790571755" ID="ID_1943399206" MODIFIED="1715790774444" TEXT="die Factory-Funktion(en) bieten eine direkte Wahlm&#xf6;glichkeit">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
...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>
<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>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1715725950719" ID="ID_1150594476" MODIFIED="1715725971326" TEXT="Testf&#xe4;lle vereinfachen">
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1715782655513" ID="ID_563670116" MODIFIED="1715782671674" TEXT="Basis-Testf&#xe4;lle anpassen">
<icon BUILTIN="flag-yellow"/>
<node CREATED="1715782937567" ID="ID_1781763433" MODIFIED="1715782940506" TEXT="checkAllocation">
<node CREATED="1715782941338" ID="ID_1181401769" MODIFIED="1715782954296" TEXT="bef&#xfc;llt eine Menge von AllocationClustern"/>
<node CREATED="1715782956114" ID="ID_1377313031" MODIFIED="1715782963361" TEXT="Checksumme mu&#xdf; nacher stimmen"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1715782964658" ID="ID_591639407" MODIFIED="1715782969617" TEXT="Typ/API-Anpassungen">
<icon BUILTIN="flag-yellow"/>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1715782638192" ID="ID_811924052" MODIFIED="1715782653285" TEXT="Tests mit Multithreading-Bezug zur&#xfc;ckbauen">
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1715783068923" ID="ID_34296369" MODIFIED="1715783077530" TEXT="Tests f&#xfc;r Error-Handling zur&#xfc;ckbauen">
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1715782674401" ID="ID_1481008630" MODIFIED="1715782690591" TEXT="neue Tests f&#xfc;r Verwendung mit STL-Container">
<icon BUILTIN="flag-yellow"/>
</node>
</node>
</node>
</node>
@ -81855,6 +81943,171 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node CREATED="1715623566743" ID="ID_688601712" MODIFIED="1715624494222" TEXT="AllocationCluster">
<linktarget COLOR="#816f7b" DESTINATION="ID_688601712" ENDARROW="Default" ENDINCLINATION="95;-321;" ID="Arrow_ID_859179840" SOURCE="ID_303611553" STARTARROW="None" STARTINCLINATION="-264;24;"/>
<linktarget COLOR="#816f7b" DESTINATION="ID_688601712" ENDARROW="Default" ENDINCLINATION="95;-321;" ID="Arrow_ID_1440452458" SOURCE="ID_1219678116" STARTARROW="None" STARTINCLINATION="-521;38;"/>
<node CREATED="1715786334834" ID="ID_885525745" MODIFIED="1715786341860" TEXT="Design / Systematik">
<node CREATED="1715786372102" ID="ID_1591071302" MODIFIED="1715786382355" TEXT="Aufwand f&#xfc;r Memory-Management wird geb&#xfc;ndelt"/>
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1715786522984" ID="ID_1870113951" MODIFIED="1715786580201" TEXT="Konflikt: Performance &#x27f7; Sicherheit">
<icon BUILTIN="messagebox_warning"/>
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1715786600390" ID="ID_926258994" MODIFIED="1715786621148" TEXT="konkret: werden Destruktoren aufgerufen?">
<icon BUILTIN="help"/>
<node CREATED="1715786632528" ID="ID_1174378095" MODIFIED="1715786635293" TEXT="pro">
<node CREATED="1715786712311" ID="ID_343417643" MODIFIED="1715787719344" TEXT="t&#xfc;ckisches Wartungs-Risiko">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
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>
</node>
<node CREATED="1715786638937" ID="ID_220404719" MODIFIED="1715787515314" TEXT="C++ Basis-Kontrakt: Determinismus">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
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>
</node>
<node CREATED="1715787292122" ID="ID_882850258" MODIFIED="1715787964678" TEXT="es ist ein weit-reichendes Subsystem">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
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>
</node>
</node>
<node CREATED="1715786776566" ID="ID_1885525073" MODIFIED="1715786778242" TEXT="contra">
<node CREATED="1715786936089" ID="ID_853557707" MODIFIED="1715788899468" TEXT="nicht-triviale Kosten">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
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>
</node>
<node CREATED="1715786779246" ID="ID_1339652048" MODIFIED="1715788973479">
<richcontent TYPE="NODE"><html>
<head>
</head>
<body>
<p>
in der Regel sind es<i>&#160;cold pages</i>
</p>
</body>
</html>
</richcontent>
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
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>
</node>
<node CREATED="1715786817201" ID="ID_1883341443" MODIFIED="1715789112354" TEXT="90% der F&#xe4;lle brauchen keinen dtor-Aufruf">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
...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>
</node>
<node CREATED="1715786961514" ID="ID_1214786701" MODIFIED="1715789369565" TEXT="es handelt sich um einer permanent-laufende Aktivit&#xe4;t">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
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>
</node>
</node>
<node CREATED="1715789372444" ID="ID_869337683" MODIFIED="1715789375047" TEXT="Diskussion">
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1715789376067" ID="ID_1679838911" MODIFIED="1715789555443" TEXT="Gefahr: premature optimisation">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
das ist &#187;der Klassiker&#171;.
</p>
<p>
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>
<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">
<icon BUILTIN="clanbomber"/>
</node>
<node CREATED="1715789594462" ID="ID_384946802" MODIFIED="1715789679723" TEXT="meine Richtlinie bisher war: Optimierungen nur in klar eingekapselten Strukturen">
<icon BUILTIN="yes"/>
</node>
<node CREATED="1715789711487" ID="ID_654621792" MODIFIED="1715789727952" TEXT="der Allokator wird nur eingef&#xfc;hrt, um sich sp&#xe4;ter Handlungs-Optionen zu schaffen"/>
<node CREATED="1715789696009" ID="ID_1534276155" MODIFIED="1715789769429" TEXT="eigentlich kann ich derzeit die Entscheidung nicht rational treffen"/>
<node CREATED="1715789753089" ID="ID_1651672024" MODIFIED="1715789767679" TEXT="absehbar ist jedoch da&#xdf; hier ein gro&#xdf;er Hebel gegeben ist"/>
<node CREATED="1715789799595" ID="ID_630552591" MODIFIED="1715790098609" TEXT="eine &#xbb;Alles oder NIchts&#xab;-Entscheidung ist sp&#xe4;ter mindestens genauso schwer">
<richcontent TYPE="NOTE"><html>
<head>
</head>
<body>
<p>
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>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#ccb59b" COLOR="#6e2a38" CREATED="1715790111369" ID="ID_1057200272" MODIFIED="1715790132010" TEXT="Fazit: Kompromi&#xdf; suchen">
<font ITALIC="true" NAME="SansSerif" SIZE="14"/>
<icon BUILTIN="yes"/>
<node CREATED="1715790137116" ID="ID_609184098" MODIFIED="1715790158047" TEXT="es wird explizit eine Registrierung f&#xfc;r clean-up vorgesehen"/>
<node CREATED="1715790158683" ID="ID_863625795" MODIFIED="1715790174701" TEXT="diese bleibt aber getrennt vom eigentlichen Allokations-Management"/>
<node CREATED="1715790293402" ID="ID_412040509" MODIFIED="1715790393998" TEXT="sie wird per convenience-Shortcut an den Allocation-Cluster gebunden">
<arrowlink COLOR="#af578d" DESTINATION="ID_878890004" ENDARROW="Default" ENDINCLINATION="-446;33;" ID="Arrow_ID_464677545" STARTARROW="None" STARTINCLINATION="-568;-24;"/>
</node>
</node>
</node>
</node>
</node>
<node CREATED="1715623570769" ID="ID_582193119" MODIFIED="1715623580607" TEXT="Allokations-Verwaltung per Segment"/>
</node>