BufferProvider: lift the family-ID to the BufferStage level
During the last days, I started with analysis to find a way to operate the `BufferProvider`, as implemented thus far, within a massively concurrent environment. Since I intend to create thread-local caches, the initialisation of the `BufferMetadata` store must be static. It turns out that the root-ID, which acts like a mandator ID, is only used at a single code path, when creating or accessing an abstract type-Key. It is thus easy to extract and relocate this distinguishing ID into the actual `BufferStage` implementation.
This commit is contained in:
parent
4dc6885665
commit
8d563d1ea9
4 changed files with 658 additions and 46 deletions
|
|
@ -20,7 +20,7 @@
|
|||
** expose the correct buffer for each request. Typically -- and independent of the actual
|
||||
** implementation -- the following properties need to be tracked
|
||||
** - that overall storage size available within the buffer
|
||||
** - a pair of custom \em creator and \em destructor functions to use together with this buffer
|
||||
** - a pair of custom _creator_ and _destructor_ functions to use together with this buffer
|
||||
** - an additional client key to distinguish otherwise otherwise identical client requests
|
||||
** These three distinctions are applied in sequence, thus forming a type tree with 3 levels.
|
||||
** Only the first distinguishing level (the size) is mandatory. The others are provided,
|
||||
|
|
@ -34,7 +34,10 @@
|
|||
** [Buffer Descriptor](\ref BuffDescr), embedded into each BuffHandle. While the engine
|
||||
** mostly uses these handles in the way of a pointer, the buffer descriptor acts as a
|
||||
** configuration tag attached to the buffer access, allowing to re-access a context
|
||||
** within the buffer provider implementation.
|
||||
** within the buffer provider implementation. Notably the Render Engine employs
|
||||
** several BufferProvider services (Memory, Cache, Output) that share the metadata
|
||||
** table, albeit with thread-local caches. For this reason, the registered types
|
||||
** are anchored at a root-hash, allowing to keep those several clients apart.
|
||||
**
|
||||
** @todo 2/2026 After refactoring the BufferProvider and splitting up the implementation
|
||||
** in two realms (state and storage), the purpose of this code her became much
|
||||
|
|
@ -54,7 +57,6 @@
|
|||
|
||||
|
||||
#include "lib/error.hpp"
|
||||
#include "lib/symbol.hpp"
|
||||
#include "lib/hash-value.h"
|
||||
#include "lib/util-foreach.hpp"
|
||||
#include "include/logging.h"
|
||||
|
|
@ -70,7 +72,6 @@ namespace vault{
|
|||
namespace mem {
|
||||
|
||||
using lib::HashVal;
|
||||
using lib::Literal;
|
||||
using util::for_each;
|
||||
|
||||
namespace err = lumiera::error;
|
||||
|
|
@ -557,23 +558,25 @@ namespace mem {
|
|||
* Registry for managing buffer metadata.
|
||||
* This is an implementation level service,
|
||||
* used by the standard BufferProvider implementation.
|
||||
* Each metadata registry (instance) defines and maintains
|
||||
* a family of "buffer types"; beyond the buffer storage size,
|
||||
* the concrete meaning of those types is tied to the corresponding
|
||||
* BufferProvider implementation and remains opaque. These types are
|
||||
* represented as hierarchically linked hash keys. The implementation
|
||||
* may bind a TypeHandler to a specific type, allowing automatic invocation
|
||||
* of a "constructor" and "destructor" function on each buffer of this type,
|
||||
* when _locking_ or _freeing_ the corresponding buffer.
|
||||
* @todo 2/2026 must extract an interface here..... //////////////////////////////////////////////////////TICKET #1410 : clean-up BufferProvider base implementation
|
||||
*
|
||||
* A metadata registry defines and maintains several families
|
||||
* of "buffer types"; beyond the buffer storage size, the concrete
|
||||
* meaning of those types is tied to the corresponding BufferProvider
|
||||
* implementation and remains opaque. These types are represented as
|
||||
* hierarchically linked hash keys. The implementation may bind a
|
||||
* TypeHandler to a specific type, allowing automatic invocation
|
||||
* of a "constructor" and "destructor" function on each buffer
|
||||
* of this type, when _locking_ or _freeing_ the corresponding
|
||||
* buffer. When creating or accessing a top-level (type)-Key,
|
||||
* a hash-ID of the "family" must be provided; this is a
|
||||
* root anchor and allows several clients to use a common
|
||||
* metadata table
|
||||
* @remark in the Render Engine there can be several
|
||||
* BufferProvider services, while the BufferMetadata
|
||||
* uses a common setup with thread-local caches.
|
||||
*/
|
||||
class BufferMetadata
|
||||
: util::NonCopyable
|
||||
{
|
||||
Literal id_;
|
||||
HashVal family_;
|
||||
|
||||
metadata::Table table_;
|
||||
///////////////////////////TICKET #854 : ensure proper locking happens "somewhere" when mutating metadata
|
||||
|
||||
|
|
@ -588,9 +591,8 @@ namespace mem {
|
|||
* @param implementationID to distinguish families of
|
||||
* type keys belonging to different registries.
|
||||
*/
|
||||
BufferMetadata (Literal implementationID)
|
||||
: id_(implementationID)
|
||||
, family_(hash_value(id_))
|
||||
BufferMetadata()
|
||||
: table_{}
|
||||
{ }
|
||||
|
||||
/** combine the distinguishing properties
|
||||
|
|
@ -602,14 +604,16 @@ namespace mem {
|
|||
* the third level. All these levels describe abstract type
|
||||
* keys, not entries for concrete buffers. The latter are
|
||||
* always created as children of a known type key.
|
||||
* @param familyID root anchor to keep mandators apart
|
||||
*/
|
||||
Key
|
||||
key (size_t storageSize
|
||||
key (HashVal familyID
|
||||
,size_t storageSize
|
||||
,TypeHandler instanceFunc =TypeHandler::RAW
|
||||
,LocalTag specifics =LocalTag::UNKNOWN)
|
||||
{
|
||||
REQUIRE (storageSize);
|
||||
Key typeKey = trackKey (family_, storageSize);
|
||||
Key typeKey = trackKey (familyID, storageSize);
|
||||
|
||||
if (nontrivial(instanceFunc))
|
||||
typeKey = trackKey (typeKey, instanceFunc);
|
||||
|
|
@ -826,6 +830,9 @@ namespace mem {
|
|||
{
|
||||
if (isKnown (key)) return;
|
||||
table_.store (Entry{key, nullptr});
|
||||
// stored a type marker entry with this key
|
||||
ENSURE (HashVal(key) == HashVal(get(key)));
|
||||
ENSURE (get(key).isTypeKey());
|
||||
}
|
||||
|
||||
/** store a fully populated entry immediately starting with locked state
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ namespace mem {
|
|||
class SimpleBufferStateRegistry
|
||||
: public BufferProviderSetup::Stage
|
||||
{
|
||||
HashVal familyID_;
|
||||
BufferMetadata metadata_;
|
||||
|
||||
/* === BufferStage interface === */
|
||||
|
|
@ -68,8 +69,8 @@ namespace mem {
|
|||
ID
|
||||
defineBufferType (size_t buffSiz, TypeHandler handlerFunctions, LocalTag localTag)
|
||||
{
|
||||
return lookup (metadata_.key (buffSiz, move (handlerFunctions), localTag));
|
||||
} // deliberately: create storage, and return reference to it
|
||||
return lookup (metadata_.key (familyID_, buffSiz, move (handlerFunctions), localTag));
|
||||
} // deliberately: maybe create storage, and return reference to it
|
||||
|
||||
ID
|
||||
mark_locked (ID typeKey, BuffAlloc alloc) override
|
||||
|
|
@ -111,7 +112,8 @@ namespace mem {
|
|||
|
||||
public:
|
||||
SimpleBufferStateRegistry (Literal implementationID)
|
||||
: metadata_{implementationID}
|
||||
: familyID_{hash_value (implementationID)}
|
||||
, metadata_{}
|
||||
{ }
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include "test/test-helper.hpp"
|
||||
#include "vault/mem/buffhandle.hpp"
|
||||
#include "vault/mem/buffer-metadata.hpp"
|
||||
#include "lib/symbol.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
#include <memory>
|
||||
|
|
@ -34,6 +35,7 @@ using test::testData;
|
|||
using util::isSameObject;
|
||||
using util::isnil;
|
||||
using lib::randStr;
|
||||
using lib::Literal;
|
||||
|
||||
namespace vault {
|
||||
namespace mem {
|
||||
|
|
@ -85,7 +87,10 @@ namespace test {
|
|||
size_t SIZE_A{0};
|
||||
size_t SIZE_B{0};
|
||||
|
||||
/** common Metadata table to be tested */
|
||||
/// root anchor for all type-keys, similar to a mandator ID
|
||||
HashVal FAM{hash_value (Literal{"BufferMetadata_test"})};
|
||||
|
||||
/// common Metadata table to be tested
|
||||
unique_ptr<BufferMetadata> meta_;
|
||||
|
||||
virtual void
|
||||
|
|
@ -106,11 +111,11 @@ namespace test {
|
|||
ensure_proper_fixture()
|
||||
{
|
||||
if (!meta_)
|
||||
meta_.reset(new BufferMetadata("BufferMetadata_test"));
|
||||
meta_.reset(new BufferMetadata);
|
||||
|
||||
return (SIZE_A != SIZE_B)
|
||||
and (JUST_SOMETHING != meta_->key(SIZE_A))
|
||||
and (JUST_SOMETHING != meta_->key(SIZE_B))
|
||||
and (JUST_SOMETHING != meta_->key(FAM, SIZE_A))
|
||||
and (JUST_SOMETHING != meta_->key(FAM, SIZE_B))
|
||||
;
|
||||
}
|
||||
|
||||
|
|
@ -119,11 +124,11 @@ namespace test {
|
|||
verifyBasicProperties()
|
||||
{
|
||||
// retrieve some type keys
|
||||
metadata::Key key = meta_->key(SIZE_A);
|
||||
metadata::Key key = meta_->key(FAM, SIZE_A);
|
||||
CHECK (key);
|
||||
|
||||
metadata::Key key1 = meta_->key(SIZE_A);
|
||||
metadata::Key key2 = meta_->key(SIZE_B);
|
||||
metadata::Key key1 = meta_->key(FAM, SIZE_A);
|
||||
metadata::Key key2 = meta_->key(FAM, SIZE_B);
|
||||
CHECK (key1);
|
||||
CHECK (key2);
|
||||
CHECK (key == key1);
|
||||
|
|
@ -204,10 +209,10 @@ namespace test {
|
|||
{
|
||||
// to build a descriptor for a buffer holding a TestFrame
|
||||
TypeHandler attachTestFrame = TypeHandler::create<TestFrame>();
|
||||
metadata::Key bufferType1 = meta_->key(sizeof(TestFrame), attachTestFrame);
|
||||
metadata::Key bufferType1 = meta_->key(FAM, sizeof(TestFrame), attachTestFrame);
|
||||
|
||||
// to build a descriptor for a raw buffer of size SIZE_B
|
||||
metadata::Key rawBuffType = meta_->key(SIZE_B);
|
||||
metadata::Key rawBuffType = meta_->key(FAM, SIZE_B);
|
||||
|
||||
// to announce using a number of buffers of this type
|
||||
LocalTag transaction1(1);
|
||||
|
|
@ -321,7 +326,7 @@ namespace test {
|
|||
verifyStateMachine()
|
||||
{
|
||||
// start with building a type key....
|
||||
metadata::Key key = meta_->key(SIZE_A);
|
||||
metadata::Key key = meta_->key(FAM, SIZE_A);
|
||||
CHECK (NIL == meta_->get(key).state());
|
||||
CHECK (meta_->get(key).isTypeKey());
|
||||
CHECK (not meta_->isLocked(key));
|
||||
|
|
|
|||
|
|
@ -77868,6 +77868,63 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1776202406458" ID="ID_1592585058" MODIFIED="1776203851816" TEXT="Verbindung zwischen StreamType-ImplType und Buffer-typeID zeichnet sich ab">
|
||||
<arrowlink COLOR="#d75c58" DESTINATION="ID_817437949" ENDARROW="Default" ENDINCLINATION="594;-20;" ID="Arrow_ID_1233499517" STARTARROW="None" STARTINCLINATION="629;24;"/>
|
||||
<arrowlink COLOR="#eb5e70" DESTINATION="ID_967352308" ENDARROW="Default" ENDINCLINATION="1756;0;" ID="Arrow_ID_273064285" STARTARROW="None" STARTINCLINATION="604;22;"/>
|
||||
<arrowlink COLOR="#d05b84" DESTINATION="ID_493181849" ENDARROW="Default" ENDINCLINATION="999;0;" ID="Arrow_ID_1009980554" STARTARROW="None" STARTINCLINATION="459;17;"/>
|
||||
<node CREATED="1776203007056" ID="ID_155729424" MODIFIED="1776203019574" TEXT="hier entsteht Layering der Bestimmungen">
|
||||
<node CREATED="1776203032173" ID="ID_702428578" MODIFIED="1776203174358" TEXT="Domain-Ontology">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
enthält implizit ein System der Bedingtheiten: bestimmte »Arten« von Daten können bearbeitet und transformiert werden, bisweileilen ist eine Adaptierung möglich, aber manche Verbindungen sind „ganz offensichtlich“ nicht möglich. Im Rahmen einer Domain-Ontology sind deratige Zusammenhänge zumeist unmittelbar gegeben, und werden daher oft gar nicht richtig ausformuliert
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1776203181668" ID="ID_319859218" MODIFIED="1776203289566" TEXT="High-Level-Model">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Hier werden nur symbolische Repräsentationen der Bezüge in eine Domain-Ontology festgehalten, und hinter der Konzeption eines »Asset« zusammengefaßt. In der Regel ist das hier nur ein indirekter Verweis: von einer Medien, oder Processor-ID kommt man auf die dahinter liegende Domain-Ontology, die letztlich die Frage beantworden muß, ob »etwas geht«
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1776203291856" ID="ID_1872157292" MODIFIED="1776203430615" TEXT="Builder">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Das ist die einzige Stelle, and der alle Bezüge konkret aufgelöst und neu verknüpft werden müssen; wenn im Rahmen einer Processing-Pipeline ein Abschnitt »auf« einem bestimmten StreamType »laufen« muß, dann wird ein StreamType-ImplementationType benötigt; dieser legt u.A. die benöigten Buffer fest ⟹ der Builder hält dies in Form eines Buffer-Descriptors fest, und bettet diesen in die Render-Nodes ein
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1776203432267" ID="ID_687643706" MODIFIED="1776203531666" TEXT="Buffer-Metadata">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Hier entspricht der Buffer-Descriptor einer Buffer typeID, welche irgenwann einmal von „jemandem“ aufgelöst und zugeordnet wurde; diese Zuordnung ist auf dieser Ebene in der Engine bereits nur noch implizit in das Node-Network »gebacken«, und zeigt sich nur in Form der hinterlegten Buffer-Descriptoren und Render-Funktionen.
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1776203542860" ID="ID_1847879822" MODIFIED="1776203662093" TEXT="Buffer-Store">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Dieser läuft im Wesentlichen Thread-local; er erzeugt im Moment der tatsächlichen Buffer-Zuordnung einen sub-Key, den »stateKey« — und im zugehörigen Metadaten-Eintrag speichert der BufferStore wichtige Verwaltungsinformationen, wie MRU-Daten
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1719689444617" ID="ID_1839118482" MODIFIED="1719689676839" STYLE="fork" TEXT="Implementierung">
|
||||
|
|
@ -91695,6 +91752,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node CREATED="1715177649235" ID="ID_732364224" MODIFIED="1715177654639" TEXT="StreamType-*"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#d3c798" COLOR="#990000" CREATED="1715177776654" ID="ID_817437949" MODIFIED="1736107728590" TEXT="Verbindung zwischen StreamType (ImplFacade) und konkreten Buffer-Layout">
|
||||
<linktarget COLOR="#d75c58" DESTINATION="ID_817437949" ENDARROW="Default" ENDINCLINATION="594;-20;" ID="Arrow_ID_1233499517" SOURCE="ID_1592585058" STARTARROW="None" STARTINCLINATION="629;24;"/>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -99651,6 +99709,18 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</html></richcontent>
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node CREATED="1776202642967" ID="ID_493181849" MODIFIED="1776202757042" TEXT="eine mögliche Verbindung läuft über die Buffer-Metadaten (Buffer-typeID)">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...denn dort ist nicht nur die Buffer-size, sonder ggfs. auch ein TypeHandler hinterlegt. Alle diese Informationen zusammen werden abstrakt repräsentiert als Buffer-Descriptor, und in dieser Form auch schon vom Builder angelegt und in die Nodes eingebettet
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<linktarget COLOR="#d05b84" DESTINATION="ID_493181849" ENDARROW="Default" ENDINCLINATION="999;0;" ID="Arrow_ID_1009980554" SOURCE="ID_1592585058" STARTARROW="None" STARTINCLINATION="459;17;"/>
|
||||
<icon BUILTIN="info"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1719627010609" ID="ID_1087699314" MODIFIED="1719627015478" TEXT="Beispiele durchgehen">
|
||||
|
|
@ -106146,8 +106216,9 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<font NAME="SansSerif" SIZE="11"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1771465174999" ID="ID_1884464720" LINK="https://issues.lumiera.org/ticket/1411" MODIFIED="1771465865302" TEXT="#1411 Aliasing of Buffer TypeHandler instances">
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1771465174999" ID="ID_1884464720" LINK="https://issues.lumiera.org/ticket/1411" MODIFIED="1776202055802" TEXT="#1411 Aliasing of Buffer TypeHandler instances">
|
||||
<linktarget COLOR="#f3173a" DESTINATION="ID_1884464720" ENDARROW="Default" ENDINCLINATION="650;39;" ID="Arrow_ID_125159421" SOURCE="ID_983442728" STARTARROW="None" STARTINCLINATION="838;36;"/>
|
||||
<linktarget COLOR="#f62244" DESTINATION="ID_1884464720" ENDARROW="Default" ENDINCLINATION="929;56;" ID="Arrow_ID_1092187353" SOURCE="ID_1218434069" STARTARROW="Default" STARTINCLINATION="652;-35;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -106175,15 +106246,23 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node CREATED="1731889697236" ID="ID_1573431621" MODIFIED="1731889706151" TEXT="StreamType / ImplType?"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1731890121591" HGAP="46" ID="ID_1319945622" MODIFIED="1735004946234" TEXT="wird relevant in dem Moment wo wir aufrufen wollen...." VSHIFT="-1">
|
||||
<arrowlink COLOR="#e0092c" DESTINATION="ID_1476280091" ENDARROW="Default" ENDINCLINATION="60;-97;" ID="Arrow_ID_602010804" STARTARROW="None" STARTINCLINATION="-541;28;"/>
|
||||
<arrowlink COLOR="#0933e0" DESTINATION="ID_1476280091" ENDARROW="Default" ENDINCLINATION="60;-97;" ID="Arrow_ID_602010804" STARTARROW="None" STARTINCLINATION="-541;28;"/>
|
||||
<linktarget COLOR="#bb4c6b" DESTINATION="ID_1319945622" ENDARROW="Default" ENDINCLINATION="-663;35;" ID="Arrow_ID_542692149" SOURCE="ID_447051297" STARTARROW="None" STARTINCLINATION="745;112;"/>
|
||||
<icon BUILTIN="flag-pink"/>
|
||||
<node CREATED="1776201545007" ID="ID_475307896" MODIFIED="1776201574193" TEXT="an dem Punkt muß es den Buffer-Descriptor bereits geben">
|
||||
<arrowlink DESTINATION="ID_1082706809" ENDARROW="Default" ENDINCLINATION="237;0;" ID="Arrow_ID_369900856" STARTARROW="None" STARTINCLINATION="-19;70;"/>
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1721238837562" HGAP="148" ID="ID_610272532" MODIFIED="1731890424341" STYLE="bubble" TEXT="ungelöst: Buffer-Typisierung" VSHIFT="44">
|
||||
<edge COLOR="#ff5d00" STYLE="sharp_linear"/>
|
||||
<arrowlink COLOR="#fe512a" DESTINATION="ID_1884956005" ENDARROW="Default" ENDINCLINATION="1101;-48;" ID="Arrow_ID_538032456" STARTARROW="None" STARTINCLINATION="-805;76;"/>
|
||||
<icon BUILTIN="bell"/>
|
||||
<node CREATED="1721239003353" ID="ID_1445103400" MODIFIED="1731889907429" STYLE="fork" TEXT="wer verwaltet diese Info generisch?">
|
||||
<node CREATED="1721239003353" HGAP="19" ID="ID_1445103400" MODIFIED="1776201979377" STYLE="fork" TEXT="wer verwaltet diese Info generisch?" VSHIFT="16">
|
||||
<font NAME="SansSerif" SIZE="8"/>
|
||||
</node>
|
||||
<node CREATED="1776201897896" ID="ID_1555779183" MODIFIED="1776201949957" STYLE="fork" TEXT="wie identifizieren wir Type-Handler?">
|
||||
<edge COLOR="#ff5d00" STYLE="sharp_linear" WIDTH="thin"/>
|
||||
<font NAME="SansSerif" SIZE="8"/>
|
||||
</node>
|
||||
<node CREATED="1721239003353" ID="ID_1561511907" MODIFIED="1731889878331" STYLE="fork" TEXT="wie bekommen wir eine passende Allokation?">
|
||||
|
|
@ -106197,28 +106276,63 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<arrowlink COLOR="#6c169e" DESTINATION="ID_1655919747" ENDARROW="Default" ENDINCLINATION="619;33;" ID="Arrow_ID_1405551684" STARTARROW="None" STARTINCLINATION="-249;15;"/>
|
||||
<icon BUILTIN="bell"/>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1776201446901" HGAP="31" ID="ID_1082706809" MODIFIED="1776201697309" TEXT="(inzwischen wurde deutlich: der Builder erzeugt die Buffer-Descriptoren)" VSHIFT="1">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...hier hat sich einiges geklärt im Zuge der Überarbeitung BufferProvider / OutputSlot im Frühjahr 2026. Die Buffer-Metadaten sind hierarchisch, und das übersetzt sich zur Laufzeit in eine <i>layered structure</i>
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
ein allgemeinter type-Key liegt in einer zentralen Metadaten-Tabelle
|
||||
</li>
|
||||
<li>
|
||||
thread-local gibt es einen Eintrag mit einem Sub-Typ, der auf der konkreten Buffer-Adresse basiert (und die kann es nur einmal geben)
|
||||
</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<linktarget COLOR="#a9b4c1" DESTINATION="ID_1082706809" ENDARROW="Default" ENDINCLINATION="237;0;" ID="Arrow_ID_369900856" SOURCE="ID_475307896" STARTARROW="None" STARTINCLINATION="-19;70;"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1721238814245" ID="ID_1476280091" MODIFIED="1735004940722" TEXT="Schwierigkeit: BufferProvider im OutputSlot Protokoll">
|
||||
<linktarget COLOR="#e0092c" DESTINATION="ID_1476280091" ENDARROW="Default" ENDINCLINATION="60;-97;" ID="Arrow_ID_602010804" SOURCE="ID_1319945622" STARTARROW="None" STARTINCLINATION="-541;28;"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1721238814245" ID="ID_1476280091" MODIFIED="1776201108511" TEXT="Schwierigkeit: BufferProvider im OutputSlot Protokoll">
|
||||
<linktarget COLOR="#0933e0" DESTINATION="ID_1476280091" ENDARROW="Default" ENDINCLINATION="60;-97;" ID="Arrow_ID_602010804" SOURCE="ID_1319945622" STARTARROW="None" STARTINCLINATION="-541;28;"/>
|
||||
<linktarget COLOR="#fe512a" DESTINATION="ID_1476280091" ENDARROW="Default" ENDINCLINATION="-997;55;" ID="Arrow_ID_4728843" SOURCE="ID_1160117239" STARTARROW="None" STARTINCLINATION="-865;41;"/>
|
||||
<icon BUILTIN="bell"/>
|
||||
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1735004955001" ID="ID_393137872" MODIFIED="1735005013973" TEXT="DataSink soll ein BuffHandle liefern">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#435e98" CREATED="1735004955001" ID="ID_393137872" MODIFIED="1776201051002" TEXT="DataSink soll ein BuffHandle liefern">
|
||||
<icon BUILTIN="broken-line"/>
|
||||
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1735004968712" ID="ID_62347373" MODIFIED="1735005006450" TEXT="aber BufferProvider ist nicht auf Delegieren ausgelegt">
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1735004968712" ID="ID_62347373" MODIFIED="1776201028285">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
aber BufferProvider <strike>ist nicht</strike><font color="#8221c9" size="2">(war nicht)</font> auf Delegieren ausgelegt
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
<node COLOR="#5b280f" CREATED="1735005016587" ID="ID_348220482" MODIFIED="1735005042022" TEXT="deshalb verwendet DataSink eine separate emit()-Methode">
|
||||
<icon BUILTIN="stop-sign"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fafe99" COLOR="#fa002a" CREATED="1735005044143" ID="ID_1580601333" MODIFIED="1736092914290" TEXT="die ist aber für die Node-Invocation gar nicht zugänglich">
|
||||
<node COLOR="#5b280f" CREATED="1735005044143" ID="ID_1580601333" MODIFIED="1776201046903" TEXT="die ist aber für die Node-Invocation gar nicht zugänglich">
|
||||
<linktarget COLOR="#ba0855" DESTINATION="ID_1580601333" ENDARROW="Default" ENDINCLINATION="-484;22;" ID="Arrow_ID_1229889232" SOURCE="ID_1338134836" STARTARROW="None" STARTINCLINATION="-571;787;"/>
|
||||
<linktarget COLOR="#cc0a6d" DESTINATION="ID_1580601333" ENDARROW="Default" ENDINCLINATION="-290;14;" ID="Arrow_ID_972000949" SOURCE="ID_1501030777" STARTARROW="None" STARTINCLINATION="579;-32;"/>
|
||||
<icon BUILTIN="broken-line"/>
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
<node CREATED="1776201071069" HGAP="26" ID="ID_243215236" MODIFIED="1776201094642" TEXT="4/2026 jetzt schon" VSHIFT="3">
|
||||
<icon BUILTIN="ksmiletris"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1776201119822" ID="ID_1232755696" MODIFIED="1776201351351" TEXT="Problem wurde durch Aufräumen im BufferProvider + re-Design OutputSlot gelöst">
|
||||
<arrowlink COLOR="#25fd1a" DESTINATION="ID_1552790778" ENDARROW="Default" ENDINCLINATION="59;-688;" ID="Arrow_ID_990862040" STARTARROW="None" STARTINCLINATION="-3509;123;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -122946,7 +123060,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1770827094068" FOLDED="true" ID="ID_1067363374" MODIFIED="1776112151452">
|
||||
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1770827094068" FOLDED="true" ID="ID_1067363374" MODIFIED="1776201747067">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
|
|
@ -123854,6 +123968,7 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
</node>
|
||||
<node BACKGROUND_COLOR="#d8eea9" COLOR="#014a07" CREATED="1775869057329" ID="ID_1552790778" MODIFIED="1775869604162" TEXT="aus »Vorentwurf« wurde ein Re-Design">
|
||||
<arrowlink COLOR="#6a5ffe" DESTINATION="ID_78273441" ENDARROW="Default" ENDINCLINATION="-1068;-80;" ID="Arrow_ID_1534724962" STARTARROW="None" STARTINCLINATION="1067;77;"/>
|
||||
<linktarget COLOR="#25fd1a" DESTINATION="ID_1552790778" ENDARROW="Default" ENDINCLINATION="59;-688;" ID="Arrow_ID_990862040" SOURCE="ID_1232755696" STARTARROW="None" STARTINCLINATION="-3509;123;"/>
|
||||
<linktarget COLOR="#0eb58e" DESTINATION="ID_1552790778" ENDARROW="Default" ENDINCLINATION="5;-124;" ID="Arrow_ID_729970542" SOURCE="ID_809493894" STARTARROW="None" STARTINCLINATION="-39;4;"/>
|
||||
<icon BUILTIN="forward"/>
|
||||
<node CREATED="1775869679499" ID="ID_537606249" MODIFIED="1775869698867" TEXT="das alte Design überprüft ⟶ die Grundidee war in Ordnung"/>
|
||||
|
|
@ -143539,7 +143654,38 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
</html></richcontent>
|
||||
<arrowlink COLOR="#244ad5" DESTINATION="ID_1284720886" ENDARROW="Default" ENDINCLINATION="-1522;391;" ID="Arrow_ID_597904659" STARTARROW="None" STARTINCLINATION="1182;40;"/>
|
||||
</node>
|
||||
<node CREATED="1771183400259" ID="ID_886897159" MODIFIED="1771183644696" TEXT="2026 : Konsolidierung BufferProvider-Implementierung">
|
||||
<node CREATED="1771183400259" ID="ID_886897159" MODIFIED="1776195310378" TEXT="2026 : Konsolidierung BufferProvider-Implementierung">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Nach erster Bestandsaufnahme konnte ich bestätigen, daß das <i>Buffer Provider Protocol</i> im aktuellen Horizont gut genug ist und keiner Revision unterzogen werden muß. Die massiven Probleme steckten in der Implementierung, die sich tatsächlich als eine Test-Implementierung mit Support für Tracking und nachträgliche Verifikationen herausstellt — zudem bestand hier eine giftige Verkopplung mit dem OutputSlot, für den es nichteinmal ein klares Abstraktions-Interface gab, und dessen Implementierung ein reiner Test-Entwurf war, der direkt in die BufferProvider-Implementierung eingesprungen ist.
|
||||
</p>
|
||||
<p>
|
||||
|
||||
</p>
|
||||
<p>
|
||||
Daher habe ich beschlossen, den BufferProvider <i>komplett zu »entkernen«. </i>Die bestehende Implementierungs-Logik wurde auf <b>zwei Säulen</b> aufgeteilt:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
die Metadaten-Verwaltung (Interface: <font color="#5e3f3f" face="Monospaced">BufferStage</font>)
|
||||
</li>
|
||||
<li>
|
||||
die Storage-Verwaltung  (Interface: <font color="#5e3f3f" face="Monospaced">BufferStore</font>)
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
Sodann wurde der (vorerst beiseite gestellte) alte Implementierungs-Code in dieses Schema eingefügt, und alle Teile ausgelassen und neu implementiert, die ersichtlich mit Diagnose/Tracking vermischt waren. Damit konnte die Funktionsfähigkeit auf Interface-Ebene demonstriert werden (<font color="#5e3f3f" face="Monospaced">BufferProviderProtocol_test</font>). Danach wurden die Diagnose-Tools komplett als neue Erweiterung über diese aufgeräumte Struktur gesetzt, und als sehr viel einfachere, eingekapselte, eigenständige Komponente neu entwickelt. In einem letzten Schritt konnte ich den alten Backend-Code (mit dem inzwischen stillgelegten Tracking) komplett ablösen und ebenfalls durch eine sehr einfache, »naive« Implementierung ersetzen.
|
||||
</p>
|
||||
<p>
|
||||
|
||||
</p>
|
||||
<p>
|
||||
Im Ergebnis gibt es nun eine viel flexiblere interne Struktur, in der Sub-Classing auf beiden Säulen mögich ist, oder auch Anpassung per Proxying. Die <b>Buffer-Metadaten-Implementierung</b> konnte dabei nahezu komplett so übernommen und bestätigt werden, wie sie seit 2024 vorliegt; es wurden lediglich einige API-Methoden etwas versäubert.
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<arrowlink COLOR="#5c617e" DESTINATION="ID_417601632" ENDARROW="Default" ENDINCLINATION="-1000;61;" ID="Arrow_ID_993142525" STARTARROW="None" STARTINCLINATION="-1410;73;"/>
|
||||
</node>
|
||||
<node CREATED="1775873393327" ID="ID_1254948925" MODIFIED="1775873731261" TEXT="2026 : Redesign OutputSlot">
|
||||
|
|
@ -143764,6 +143910,458 @@ StM_bind(Builder<R1> b1, Extension<R1,R2> extension)
|
|||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1776195345475" ID="ID_773105612" MODIFIED="1776195351345" TEXT="Problem der Code-Struktur">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1776195352772" ID="ID_865032756" MODIFIED="1776195928687">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
nach den Aufräum-Arbeiten liegt nun eine <i><font size="4">saubere default-Implementierung</font></i> vor
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="idea"/>
|
||||
<node CREATED="1776195410413" ID="ID_1578016013" MODIFIED="1776195421788" TEXT="dieser Mittelbau ist »stateless«"/>
|
||||
<node CREATED="1776195425260" ID="ID_870091214" MODIFIED="1776195441972" TEXT="Zustand steckt in den beiden Implementierungs-Backends">
|
||||
<node CREATED="1776195443253" ID="ID_680653382" MODIFIED="1776195450832" TEXT="Stage: Buffer-Metadaten-Tabelle"/>
|
||||
<node CREATED="1776195451804" ID="ID_1991940719" MODIFIED="1776195461215" TEXT="Store: aktuelle Speicherbelegung"/>
|
||||
</node>
|
||||
<node CREATED="1776195471387" ID="ID_1068582113" MODIFIED="1776195495322" TEXT="Zustand wird nach außen als Type-Key(Handle) repräsentiert"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fafe99" COLOR="#fa002a" CREATED="1776195497158" ID="ID_1528939449" MODIFIED="1776195528413" TEXT="dieser Code ist aber kohäsiv und nicht thread-aware">
|
||||
<icon BUILTIN="clanbomber"/>
|
||||
<node CREATED="1776195534439" ID="ID_1983847516" MODIFIED="1776195614354" TEXT="das war eine bewußte Wahl">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...um die Komplexität beherrschbar zu machen; ich habe gemerkt, daß das Durchdenken des <i>Buffer-Provider-Protocols</i> mich bereits an gedankliche Kapazitätsgrenzen bringt
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1776195641179" ID="ID_1676439249" MODIFIED="1776195725456" TEXT="allerdings sind alle Aufrufe direkte Ketten">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
also: front-end-Handle ⟶ function-call-chain ⟶ Implementierungs-Backend ⟲ Response
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1776195780538" ID="ID_364343301" MODIFIED="1776195807148" TEXT="⟹ Multithreading wird erst im jeweiligen Backend relevant">
|
||||
<node CREATED="1776195835578" ID="ID_1455463636" MODIFIED="1776195852605" TEXT="wenn ein Client-Thread einen type-Key hat/sieht ..."/>
|
||||
<node CREATED="1776195853376" ID="ID_54490595" MODIFIED="1776195872385" TEXT="kaskadiert ein Aufruf problemlos durch bist zum Lookup im Backend"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1776196576826" ID="ID_850704640" MODIFIED="1776196651213">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
⟹ die Aufgabe : <b>Thread-lokale Slices</b> schaffen
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<node CREATED="1776196622969" ID="ID_109574683" MODIFIED="1776196629161" TEXT="Anforderungen">
|
||||
<node CREATED="1776196630096" ID="ID_1510075065" MODIFIED="1776196674318" TEXT="jedes Slice muß stets von Null-auf handlungsfähig sein"/>
|
||||
<node CREATED="1776196881798" ID="ID_1250147382" MODIFIED="1776196902243" TEXT="jedes Slice muß als eigenständige Instanz mit einer Zentrale kommunizieren können"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1776196927192" ID="ID_1790936937" MODIFIED="1776196934764" TEXT="Analyse: ist das möglich?">
|
||||
<icon BUILTIN="help"/>
|
||||
<node CREATED="1776199263823" ID="ID_11659909" MODIFIED="1776199286039" TEXT="Store">
|
||||
<node CREATED="1776199287308" ID="ID_1968928582" MODIFIED="1776199292991" TEXT="erscheint einfach...."/>
|
||||
<node CREATED="1776199318668" ID="ID_236929298" MODIFIED="1776199330718" TEXT="lokaler Buffer und ansonsten...">
|
||||
<node CREATED="1776199331910" ID="ID_139914418" MODIFIED="1776199338388" TEXT="Zentrale fragen"/>
|
||||
<node CREATED="1776199339150" ID="ID_1256667957" MODIFIED="1776199341072" TEXT="Heap"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1776199346352" ID="ID_1614149847" MODIFIED="1776199348252" TEXT="Stage">
|
||||
<node CREATED="1776199351699" ID="ID_1600621472" MODIFIED="1776199412375" TEXT="die Typ-Hierarchie wird hier zur tückischen Falle">
|
||||
<node CREATED="1776199439271" ID="ID_1228644162" MODIFIED="1776200088982" TEXT="zwei parallele Threads könnten den gleichen Sub-Typ erzeugen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
dazu müßten sie allerdings die gleiche Buffer-Adresse registrieren;
|
||||
</p>
|
||||
<p>
|
||||
insofern die Buffer-Adressen vom Store-Backend stammen, und konkret einem thread-lokalen Store gehören müssen, kann <b>dieser Fall nicht auftreten</b>.
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
</node>
|
||||
<node CREATED="1776199524124" ID="ID_624621825" MODIFIED="1776200388258" TEXT="was wenn ein Thread einen bereits registrierten Typ nicht kennt?">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Aber das stellt insofern eine Gefahr dar, als daß in den dadurch erzeugten duplikaten Einträgen tatsächlich verschiedene Daten liegen könnten. Wenn dagegen zwei Threads eine neu-Registrierung machen würden, dann könnte diese einfach in die Zentrale propagiert, und dort dedupliziert werden
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1776199902638" ID="ID_1239938132" MODIFIED="1776199920202" TEXT="⟹ bedeutet: diese Gefahrsituationen müssen verhindert werden">
|
||||
<node CREATED="1776200398600" ID="ID_1570370873" MODIFIED="1776200451325" TEXT="sub-Typen hängen an der konkreten Speicher-Adresse (die unique ist)"/>
|
||||
<node CREATED="1776200454105" ID="ID_1248388353" MODIFIED="1776200473996" TEXT="problematisch sind typ-Keys, und zwar bezüglich der Type-Handler"/>
|
||||
<node CREATED="1776200497774" ID="ID_1039074673" MODIFIED="1776200508694" TEXT="Schlußfolgerungen...">
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1776200510094" ID="ID_1218434069" MODIFIED="1776202055802" TEXT="das Identitäts-Problem im Typ-Funktor muß gelöst werden">
|
||||
<arrowlink COLOR="#f62244" DESTINATION="ID_1884464720" ENDARROW="Default" ENDINCLINATION="929;56;" ID="Arrow_ID_1092187353" STARTARROW="Default" STARTINCLINATION="652;-35;"/>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1776200560492" ID="ID_394534485" MODIFIED="1776200580572" TEXT="niemals dürfen zwei verschiedene Funktionen den gleichen Hash bekommen"/>
|
||||
<node CREATED="1776200683846" ID="ID_897159086" MODIFIED="1776200690709" TEXT="erscheint lösbar">
|
||||
<node CREATED="1776200691825" ID="ID_522566119" MODIFIED="1776200705923" TEXT="entweder indem der Erzeuger eine SpecID mitliefern muß"/>
|
||||
<node CREATED="1776200706983" ID="ID_99543390" MODIFIED="1776203862174" TEXT="oder indem man auf die Funktor-Identitäten abstellt">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Das heißt, auf zwei Komponenten
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
einen C++ - Funktor-Typ
|
||||
</li>
|
||||
<li>
|
||||
die konkrete Speicheradresse eines Funktors, der als Closure fungiert.
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
Sofern man diese beiden Informationen in den Hash kombiniert, würde ein »Aliasing« verschiedener Type-Handler vermieden.
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1776202090769" ID="ID_967352308" MODIFIED="1776203851816" TEXT="redundante Duplikate des gleichen Funktors...">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Nehmen zwar Speicher weg, sind aber ansonsten harmlos, da sie funktional äquivalent sind. Vermutlich können solche Duplikate auf einer höheren Ebene vermieden werden, sofern dort ebenfalls die Metadaten-typeIDs verknüpft werden — z.B. als Teil des StreamType-Implementation-Type. Wenn letztlich der gleiche Implementation-Type auch immer den gleichen Buffer-Type referenziert, wären wir sauber.
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<linktarget COLOR="#eb5e70" DESTINATION="ID_967352308" ENDARROW="Default" ENDINCLINATION="1756;0;" ID="Arrow_ID_273064285" SOURCE="ID_1592585058" STARTARROW="None" STARTINCLINATION="604;22;"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1776203872355" ID="ID_586910446" MODIFIED="1776203924100" TEXT="Neu-Registrierung eines typeKey ist jederzeit möglich — und wird nach oben propagiert"/>
|
||||
<node CREATED="1776203930600" ID="ID_1247662701" MODIFIED="1776203991160">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
eine Anfrage nur mit gegebenem typeKey muß dagegen <b>blockend</b>  aufgelöst werden
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1776204046168" ID="ID_1917619704" MODIFIED="1776204123944" TEXT="unter dieser Maßgabe: ein Stage-Slice hat seine eigene, lokale BufferMetadata-Instanz">
|
||||
<node CREATED="1776204200537" ID="ID_1381554308" MODIFIED="1776204219236" TEXT="diese weiß zunächst nicht einmal, ob sie "lokal" ist."/>
|
||||
<node CREATED="1776204220032" ID="ID_565607454" MODIFIED="1776204230203" TEXT="Aber es braucht Methoden zur Synchronisation">
|
||||
<node CREATED="1776204237246" ID="ID_121957568" MODIFIED="1776204253671" TEXT="konkret: Übernehmen eines Metadata-Entry"/>
|
||||
<node CREATED="1776204280414" ID="ID_944581715" MODIFIED="1776204521467" TEXT="theoretisch muß hier ein ganzer Chain geliefert werden">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
möglicherweise auch praktisch, weil das Buffer-Metadaten-System offen angelegt ist; ich kann jetzt nicht alle Nutzungsmuster überblocken, und kann deshalb auch nicht entscheiden, ob garantiert nur einziger Knoten benötigt wird (was aber in der Regel der Fall sein wird, da wir derzeit noch keine Type-Refinements machen)
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1776296002882" ID="ID_1463821218" MODIFIED="1776300340560" TEXT="Neu-Einschätzung der Situation">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1776296015452" ID="ID_1553381862" MODIFIED="1776300348346" TEXT="thread_lokal hat gewisse Tücken">
|
||||
<icon BUILTIN="clanbomber"/>
|
||||
<node CREATED="1776296068447" ID="ID_882324053" LINK="https://alexander-ostrovskiy-c.co.uk/posts/thread-local-storage-in-c-best-practices-and-pitfalls/" MODIFIED="1776299538975" TEXT="Practical usage and hidden risks"/>
|
||||
<node BACKGROUND_COLOR="#fafe99" COLOR="#fa002a" CREATED="1776296046515" ID="ID_962020738" LINK="https://yosefk.com/blog/cxx-thread-local-storage-performance.html" MODIFIED="1776299543765" TEXT="Thread-local Performance">
|
||||
<icon BUILTIN="broken-line"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1776299548025" ID="ID_410006825" MODIFIED="1776299559493" TEXT="ist das jetzt schlimmmmm?">
|
||||
<icon BUILTIN="help"/>
|
||||
<node CREATED="1776299579309" ID="ID_1984164694" MODIFIED="1776300160805" TEXT="passiert dieser Zugriff auf einen Buffer auf einem relevanten Performance-Level?">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Wir bekommen also u.U einen oder mehrere Function-Calls, zusätzlich zu einer Indirektion durch einen Pointer. Nach Bauchgefühl klingt das für mich nach einem Overhead ~ 500ns. Laß uns das, angenommen, 10 mal machen müssen pro Verwemdung eines Buffer-Cycle ⟹ dann wären das 5µs Overhead. Andererseits weiß ich von meinen Scheduler-Untersuchungen, daß ein einziger Zugang zu einer atomic-Flag schon mal 30µs kosten kann. Also allein das würde den Trade-off (thread_local zu verwenden) schon rechtfertigen. Laß uns dann 50 Buffer in einem Job verwenden ⟹ dann wären das 50*5µs ≡ 250µs für einen Job der <i>mindestens 5ms</i> lang sein sollte, damit mein Scheduler-Konzept aufgeht....
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1776300163087" ID="ID_1159201025" MODIFIED="1776300573707" TEXT="habe ich mich »auf peinliche Weise« verrannt — mit diesem Buffer-Provider-Design?">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...ich meine, weil ich jetzt, kummulativ, monatelang daran herumgedoktort habe, nur um jetzt <i>nachträglich</i> das Probem mit den per-Thread-Allokatoren zu sehen?
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1776439686153" ID="ID_1557325974" MODIFIED="1776439735673">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
<u>Klar ist</u>: ich spüre <b>Gegenwind</b>
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="forward"/>
|
||||
<node CREATED="1776439765547" ID="ID_645576260" MODIFIED="1776439781590">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
besonders bei den <b>BufferMetadata</b>
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1776439782405" ID="ID_1166311821" MODIFIED="1776439855412" TEXT="die sind ohne Einsicht in dieses Problem entworfen worden">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Hier meine ich sogar das weitere Problem, nämlich daß das Buffer-Management in einem massiv-concurrent-Environment funktionieren muß
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#ccb59b" COLOR="#6e2a38" CREATED="1776305000767" ID="ID_1274607292" MODIFIED="1776305029772" TEXT="mein Bauchgefühl sagt, ich sollte das notieren und dann weiter gehen">
|
||||
<font ITALIC="true" NAME="SansSerif" SIZE="14"/>
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1776305039040" ID="ID_66491214" MODIFIED="1776305057218" TEXT="möglicherweise ist das BuffHandle die eigentliche Errungenschaft"/>
|
||||
<node CREATED="1776305059318" ID="ID_1886832076" MODIFIED="1776305082303" TEXT="wohingegen die Implementierung des BufferProviders eine Analyse unterzogen werden sollte"/>
|
||||
<node CREATED="1776305083670" ID="ID_1806403735" MODIFIED="1776305106923" TEXT="welche allerdings erst möglich wird, wenn man die Trends in einer echten Engine kennt"/>
|
||||
<node CREATED="1776305131316" ID="ID_666199695" MODIFIED="1776357974462">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
das größte Problem ist daß es eine solche <i>immer noch nicht gibt</i>
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1776305156825" ID="ID_314010206" MODIFIED="1776305166558" TEXT="und ich versteh nicht recht, warum?"/>
|
||||
<node CREATED="1776357995603" ID="ID_1210353497" MODIFIED="1776359107787" TEXT="ich weiß was ich getan habe...">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
und auch warum: ich wollte an den offensichtlichen Stellen nicht »durchmarschieren«.
|
||||
</p>
|
||||
<p>
|
||||
Ich weiß aber nicht, was dann passiert wäre, ob ich von der „offensichtlich einfachen“ Lösung weitergekommen wäre, ohne diese naheliegende Lösung dann doch letztlich komplet wieder einzureissen und das zu bauen, was ich jetzt zu bauen versuche?
|
||||
</p>
|
||||
<p>
|
||||
|
||||
</p>
|
||||
<p>
|
||||
Und noch etwas hat stets eine Rolle gespielt: ich habe mir immer die Frage gestellt, was würde passieren, wenn Du zusammen mit einem »Pragmatiker« allein im Boot sitzt? Dann stürzt sich der Pragmatiker auf das Offensichtliche und verbaut Dir alles, was Dir wichtig ist und warum Du die ganzen Mühen auf Dich nimmst. Mehr noch, ich befand mich die ganzen ersten Jahre in dieser Position, und habe nach außen hin vorgegeben, daß ich an der »pragmatischen« Lösung arbeite, wohl wissend, daß ich tatsächlich der Einzige mit entsprechendem Stehvermögen bin.
|
||||
</p>
|
||||
<p>
|
||||
|
||||
</p>
|
||||
<p>
|
||||
Insofern bin ich noch nicht <i>out of the woods,</i> und sollte keine Zeit mit Zweifeln verbringen
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1776359123481" ID="ID_935313258" MODIFIED="1776359291236">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
<b>Fazit</b>: wenn thread_local wie erwartet funktioneren würde, gäbe es kein Problem
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="forward"/>
|
||||
<node CREATED="1776359147782" ID="ID_49027423" MODIFIED="1776359159216" TEXT="als notieren wir dieses potentielle Problem"/>
|
||||
<node CREATED="1776359159957" ID="ID_611795063" MODIFIED="1776359168445" TEXT="untersuchen es ggfs. später empirisch"/>
|
||||
<node CREATED="1776359169275" ID="ID_1606858571" MODIFIED="1776359191747" TEXT="und bauen notfalls ein »ThreadLocal«, das optimal effizient ist"/>
|
||||
<node CREATED="1776359203560" ID="ID_240001081" MODIFIED="1776359249485" TEXT="⟹ den aktuellen Entwruf unter dieser Maßgabe weiterentwickeln">
|
||||
<node CREATED="1776359250702" ID="ID_1110100689" MODIFIED="1776359257699" TEXT="er ist klar strukturiert"/>
|
||||
<node CREATED="1776359258534" ID="ID_193416980" MODIFIED="1776359267522" TEXT="er enthält ein Element der Eleganz"/>
|
||||
<node CREATED="1776359271069" ID="ID_859503094" MODIFIED="1776359280656" TEXT="er ist noch nicht optimiert (was gut ist)"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1776204526672" ID="ID_961403309" MODIFIED="1776204711931" TEXT="Prototyping (testgetrieben)">
|
||||
<node CREATED="1776204565654" ID="ID_45614742" MODIFIED="1776204569140" TEXT="generischer Slice">
|
||||
<node CREATED="1776292208608" ID="ID_1141218614" MODIFIED="1776292245482" TEXT="Zweck: Anbinden eines Slice in einem normalen Objekt-Kontext">
|
||||
<node CREATED="1776292987880" ID="ID_808037956" MODIFIED="1776292998479" TEXT="Zugriff über Pointer-artige Syntax"/>
|
||||
<node CREATED="1776293021744" ID="ID_808171568" MODIFIED="1776293034905" TEXT="Problem: thread_local ist implizit statisch">
|
||||
<node CREATED="1776293040334" ID="ID_555811092" MODIFIED="1776293060463" TEXT="das heißt es ist eine »versteckte globale Variable«"/>
|
||||
<node CREATED="1776295872712" ID="ID_906429004" MODIFIED="1776295889501" TEXT="stellt das für den konkteten Use-Case überhaupt eine Beschränkung dar?">
|
||||
<node CREATED="1776295891705" ID="ID_877250740" MODIFIED="1776295921697" TEXT="ja — eine hexagonale Beschränkung: ⟹ man kann's nur einmal Unit-testen"/>
|
||||
<node CREATED="1776295943826" ID="ID_896591615" MODIFIED="1776295967932" TEXT="nein — der BufferProvider in der Engine ist sowiso ein Singleton"/>
|
||||
<node CREATED="1776436869043" ID="ID_1444097357" MODIFIED="1776439761005" TEXT="aber — Buffer-Metadata baucht eine RootID">
|
||||
<arrowlink COLOR="#5b39d7" DESTINATION="ID_1105234662" ENDARROW="Default" ENDINCLINATION="113;-353;" ID="Arrow_ID_8614584" STARTARROW="None" STARTINCLINATION="-450;30;"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1776437522354" ID="ID_1884586370" MODIFIED="1776437530564" TEXT="Bedeutung für den Lebenszyklus">
|
||||
<node CREATED="1776437601915" ID="ID_813699540" MODIFIED="1776437622336" TEXT="wäre künstlich"/>
|
||||
<node CREATED="1776437695249" ID="ID_322380530" MODIFIED="1776437901918" TEXT="instance-State führt zu Non-Deteminism">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...weil dann potentiell der State der Thread-Local-Instance davon abhängt, wann der Thread gestartet wurde im Verhältnis zur Änderung des Instance-State im Zugriffs-Pfad; zudem geht aus dem Standard nicht hervor, <i>wann konkret</i> eine einzelne thread-Lokale Instanz erzeugt wird
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1776437547951" ID="ID_1822334340" MODIFIED="1776437563496" TEXT="das LocalSlice-Objekt ist ein Monostate"/>
|
||||
<node CREATED="1776437903095" ID="ID_1647425761" MODIFIED="1776438127593" TEXT="Init-Parameter für die thread-Locals ist sinnvollerweise static constexpr">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Ich weiß nicht, ob das sogar vom Standard so verlangt wird (hab ihn nicht gelesen, und CPPReference sagt nichts dazu). Aber da die Lebensspanne nur indirekt definiert wird (lebt länger als der Thread), würde alles andere letztlich auf <i>undefined behavour</i>  hinauslaufen
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1776438375366" ID="ID_630250259" MODIFIED="1776438402243">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
⟹ muß <b>in den Typ repräsentiert</b> werden
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1776442726252" ID="ID_1448305654" MODIFIED="1776442778834" TEXT="dadurch würde »automatisch« eine einzige Metadata-Storage im System entstehen">
|
||||
<linktarget COLOR="#fefdd2" DESTINATION="ID_1448305654" ENDARROW="Default" ENDINCLINATION="480;17;" ID="Arrow_ID_972765157" SOURCE="ID_1548755064" STARTARROW="None" STARTINCLINATION="469;0;"/>
|
||||
<icon BUILTIN="idea"/>
|
||||
<node CREATED="1776442794218" HGAP="25" ID="ID_1105253979" MODIFIED="1776442814861" TEXT="man müßte dann nur noch OutputSlot »einfangen«" VSHIFT="-3"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1776438434768" ID="ID_983236748" MODIFIED="1776438441595" TEXT="Definition und Verwendung">
|
||||
<node CREATED="1776438447894" ID="ID_1968488456" MODIFIED="1776438567887" TEXT="verwendet sinnvollerweise einen CONF-Typparameter">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...denn effektiv definiert jede Kombination von Template-Parametern einen neuen Typ-Scope; aus Gründen der klaren Formulierung sollte diese Diversität in einen einzigen, benannten Parameter zusammengefaßt werden
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1776438572468" ID="ID_1804894411" MODIFIED="1776438590402" TEXT="die einzelne Instanz ist Monostate und default-konstruierbar und kopierbar"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1776204569932" ID="ID_1285006287" MODIFIED="1776204574453" TEXT="Stage-Slice"/>
|
||||
<node CREATED="1776204575221" ID="ID_869340284" MODIFIED="1776204579271" TEXT="Store-Slice"/>
|
||||
<node CREATED="1776204694205" ID="ID_1617552510" MODIFIED="1776204701641" TEXT="WorkerBufferStage">
|
||||
<node CREATED="1776436907819" ID="ID_1105234662" MODIFIED="1776439761005" TEXT="Rolle der RootID klären">
|
||||
<linktarget COLOR="#5b39d7" DESTINATION="ID_1105234662" ENDARROW="Default" ENDINCLINATION="113;-353;" ID="Arrow_ID_8614584" SOURCE="ID_1444097357" STARTARROW="None" STARTINCLINATION="-450;30;"/>
|
||||
<node CREATED="1776436962370" ID="ID_1640147854" MODIFIED="1776436990673" TEXT="dient als Parent-ID für alle abstrakten Buffer-Types"/>
|
||||
<node CREATED="1776436992946" ID="ID_1491925884" MODIFIED="1776437012665" TEXT="könnte damit wie eine Mandant-ID wirken">
|
||||
<node CREATED="1776439531426" ID="ID_1417995514" MODIFIED="1776439536521" TEXT="aktuelle Implementierung">
|
||||
<node CREATED="1776439537615" ID="ID_765591297" MODIFIED="1776439591395" TEXT="neuer Typ ⟶ BufferStage::defineBufferType() ⟶ BufferMetadata::Key"/>
|
||||
<node CREATED="1776439592374" ID="ID_195017187" MODIFIED="1776439628902" TEXT="hier wird der in der Instanz gespeicherte Family-Hash als root-Seed verwendet"/>
|
||||
<node CREATED="1776441321945" ID="ID_227233326" MODIFIED="1776441343588" TEXT="es wird möglicherweise ein neuer Entry angelegt">
|
||||
<node CREATED="1776441345413" ID="ID_1462687607" MODIFIED="1776441351904" TEXT="der Key wird systematisch konstruiert"/>
|
||||
<node CREATED="1776441353963" ID="ID_872678467" MODIFIED="1776441470139" TEXT="im Key werden die Bestimmungs-Elemente jedoch explizit mitgespeichert">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
diese Redundanz war entscheidend für die neue Implementierung des BufferProvider. Denn vermöge der Metadaten-Tabelle können wir jederzeit von einem gegebenen Hash wieder auf den Entry kommen, und somit die Storage, Size und den TypeHandler wieder zugänglich machen
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1776441476224" ID="ID_70785499" MODIFIED="1776441492245" TEXT="der angelegte Entry ist »abstrakt«, d.h. hat einen NULL-Ptr für die Storage"/>
|
||||
<node CREATED="1776441498751" ID="ID_239255386" MODIFIED="1776441539500" TEXT="der zurückgelieferte Entry kann aber bereits am Ende einer hierarchischen Kette hängen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
nämlich wenn zusätzlich zur Storage-Size auch schon ein TypeHandler und gar ein LocalTag gegeben wird
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1776442066477" ID="ID_1909295766" MODIFIED="1776442103152" TEXT="nur auf diesem Zugangsweg geht die FamilyID ein"/>
|
||||
<node CREATED="1776442525319" ID="ID_401093527" MODIFIED="1776442557719" TEXT="es gibt nur den einen Aufruf aus der BufferStage-Impl (+Tests)"/>
|
||||
<node CREATED="1776442560275" ID="ID_993355013" MODIFIED="1776442576727" TEXT="⟹ die FamilyID könnte auch als Parameter kommen"/>
|
||||
</node>
|
||||
<node CREATED="1776442580542" ID="ID_1214945994" MODIFIED="1776442607448" TEXT="es wäre ohne Weiteres möglich, die Family-ID in die Buffer-Stage-Implementierung zu heben">
|
||||
<icon BUILTIN="idea"/>
|
||||
<node CREATED="1776442609827" ID="ID_570121338" MODIFIED="1776442627773" TEXT="damit wäre sie aus der »Thread-Local-Zone« raus"/>
|
||||
<node CREATED="1776442630476" ID="ID_1314697653" MODIFIED="1776442651841" TEXT="und eine einzige BufferMetadata-Storage könnte alle BufferProvider im Stystem bedienen"/>
|
||||
<node CREATED="1776442666774" ID="ID_1548755064" MODIFIED="1776442784578" TEXT="das würde dann sogar implizit passieren — weil thread_local ⟹ static">
|
||||
<arrowlink COLOR="#fefdd2" DESTINATION="ID_1448305654" ENDARROW="Default" ENDINCLINATION="480;17;" ID="Arrow_ID_972765157" STARTARROW="None" STARTINCLINATION="469;0;"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1776204702568" ID="ID_1197574712" MODIFIED="1776204706747" TEXT="WorkerBufferStore"/>
|
||||
<node CREATED="1776204787207" ID="ID_1425789996" MODIFIED="1776204792254" TEXT="vorerst nur anlegen">
|
||||
<node CREATED="1776204765269" ID="ID_1404790840" MODIFIED="1776204785977" TEXT="EngineBufferMetadata"/>
|
||||
<node CREATED="1776204795573" ID="ID_1001789565" MODIFIED="1776204802934" TEXT="EngineBufferManager"/>
|
||||
</node>
|
||||
<node CREATED="1776442826894" ID="ID_509761355" MODIFIED="1776442834087" TEXT="OutputSlot mit integrieren">
|
||||
<node CREATED="1776442835820" ID="ID_1709918207" MODIFIED="1776442866636" TEXT="der integrierte OutputBufferProxy hat auch eine BufferStage-Implementierung"/>
|
||||
<node CREATED="1776442867383" ID="ID_1166356526" MODIFIED="1776442917901" TEXT="diese ist bisher hart gecodet — könnte natürlich (statisch) konfigurierbar sein"/>
|
||||
<node CREATED="1776442948509" ID="ID_652246892" MODIFIED="1776443208611" TEXT="OutputSlot hinter BuffHandle versteckt ⟹ Überlegungen zum BufferProvider gelten analog">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Konkret:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
OutputSlot ist (neuerdings) ein ref-counting front-End-Handle. Es kann per Ref oder Kopie weitergereicht werden
|
||||
</li>
|
||||
<li>
|
||||
wo die Connection-Impl gespeichert wird, bestimmt der OutputManager
|
||||
</li>
|
||||
<li>
|
||||
die jeweilige JobInvocation gibt das BuffHandle vom OutputSlot als Ausgabe-Buffer in den Node-pull()
|
||||
</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1776443222077" ID="ID_1588377123" MODIFIED="1776443240902" TEXT="AUA! an die Concurrency in OutputSlot habe ich noch gar nicht gedacht">
|
||||
<icon BUILTIN="smily_bad"/>
|
||||
<node CREATED="1776443274627" ID="ID_1179051881" MODIFIED="1776443293851" TEXT="jeder Frame-Ausgabevorgang kann aus einem anderen Thread kommen"/>
|
||||
<node CREATED="1776443294663" ID="ID_603938434" MODIFIED="1776443307734" TEXT="allerdings wird niemals der gleiche Frame contended"/>
|
||||
<node CREATED="1776443311725" ID="ID_1518887346" MODIFIED="1776443326639" TEXT="und der Slot ist für einen einzigen Play-Prozeß"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1702414560197" ID="ID_1321884127" MODIFIED="1702414571124" TEXT="Verhalten unter echter Last beobachten">
|
||||
|
|
|
|||
Loading…
Reference in a new issue