Block-Flow: introduce config through a policy mix-in
...measured running time reproduced unaltered for -O3
This commit is contained in:
parent
5803fed544
commit
ca502aa826
4 changed files with 242 additions and 150 deletions
|
|
@ -54,6 +54,7 @@ namespace gear {
|
|||
|
||||
// using util::isnil;
|
||||
// using std::string;
|
||||
using BlockFlowAlloc = BlockFlow<blockFlow::RenderConfig>;
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -64,11 +65,11 @@ namespace gear {
|
|||
*/
|
||||
class ActivityLang
|
||||
{
|
||||
BlockFlow& mem_;
|
||||
BlockFlowAlloc& mem_;
|
||||
|
||||
public:
|
||||
// explicit
|
||||
ActivityLang (BlockFlow& memManager)
|
||||
ActivityLang (BlockFlowAlloc& memManager)
|
||||
: mem_{memManager}
|
||||
{ }
|
||||
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ namespace gear {
|
|||
struct DefaultConfig
|
||||
{
|
||||
/* === characteristic parameters === */
|
||||
const size_t EPOCH_SIZ = 100; ///< Number of storage slots to fit into one »Epoch«
|
||||
const static size_t EPOCH_SIZ = 100; ///< Number of storage slots to fit into one »Epoch«
|
||||
const Duration DUTY_CYCLE{FSecs(1)}; ///< typical relaxation time or average pre-roll to deadline
|
||||
const size_t INITIAL_STREAMS = 2; ///< Number of streams with TYPICAL_FPS to expect for normal use
|
||||
|
||||
|
|
@ -153,125 +153,183 @@ namespace gear {
|
|||
struct RenderConfig
|
||||
: DefaultConfig
|
||||
{
|
||||
|
||||
const static size_t EPOCH_SIZ = 300;
|
||||
const size_t INITIAL_STREAMS = 4;
|
||||
};
|
||||
|
||||
/**
|
||||
* Policy template to mix into the BlockFlow allocator,
|
||||
* providing the parametrisation for self-regulation
|
||||
*/
|
||||
template<class CONF>
|
||||
struct Strategy
|
||||
: CONF
|
||||
{
|
||||
|
||||
CONF const&
|
||||
config() const
|
||||
{ // Meyers Singleton
|
||||
static const CONF configInstance;
|
||||
return configInstance;
|
||||
}
|
||||
|
||||
size_t
|
||||
framesPerEpoch() const
|
||||
{
|
||||
return config().EPOCH_SIZ / config().ACTIVITIES_PER_FRAME;
|
||||
}
|
||||
|
||||
const FrameRate
|
||||
initialFrameRate() const
|
||||
{
|
||||
return config().INITIAL_STREAMS * config().TYPICAL_FPS;
|
||||
}
|
||||
|
||||
Duration
|
||||
initialEpochStep() const
|
||||
{
|
||||
return framesPerEpoch() / initialFrameRate();
|
||||
}
|
||||
|
||||
size_t
|
||||
initialEpochCnt() const ///< reserve allocation headroom for two duty cycles
|
||||
{
|
||||
return 1 + 2*_raw(config().DUTY_CYCLE) / _raw(initialEpochStep());
|
||||
}
|
||||
|
||||
double
|
||||
boostFactor() const
|
||||
{
|
||||
return config().BOOST_FACTOR;
|
||||
}
|
||||
|
||||
double
|
||||
boostFactorOverflow() const ///< reduced logarithmically, since overflow is detected on individual allocations
|
||||
{
|
||||
return pow(config().BOOST_FACTOR, 5.0/config().EPOCH_SIZ);
|
||||
}
|
||||
|
||||
Duration
|
||||
timeStep_cutOff() const ///< prevent stalling Epoch progression when reaching saturation
|
||||
{
|
||||
return _raw(initialEpochStep()) / config().OVERLOAD_LIMIT;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Allocation Extent holding _scheduler Activities_ to be performed altogether
|
||||
* before a common _deadline._ Other than the underlying raw Extent, the Epoch
|
||||
* maintains a deadline time and keeps track of storage slots already claimed.
|
||||
* This is achieved by using the Activity record in the first slot as a GATE term
|
||||
* to maintain those administrative information.
|
||||
* @remark rationale is to discard the Extent as a whole, once deadline passed.
|
||||
*/
|
||||
template<class ALO>
|
||||
class Epoch
|
||||
: public ALO::Extent
|
||||
{
|
||||
using RawIter = typename ALO::iterator;
|
||||
using SIZ = typename ALO::Extent::SIZ;
|
||||
|
||||
/// @warning will be faked, never constructed
|
||||
Epoch() = delete;
|
||||
|
||||
public:
|
||||
/**
|
||||
* specifically rigged GATE Activity,
|
||||
* used for managing Epoch metadata
|
||||
* - the Condition::rest tracks pending async IO operations
|
||||
* - the Condition::deadline is the nominal deadline of this Epoch
|
||||
* - the field `next` points to the next free allocation Slot to use
|
||||
*/
|
||||
struct EpochGate
|
||||
: Activity
|
||||
{
|
||||
/** @note initially by default there is...
|
||||
* - effectively no deadline
|
||||
* - no IO operations pending (i.e. we can just discard the Epoch)
|
||||
* - the `next` usable Slot is the last Storage slot, and will be
|
||||
* decremented until there is only one slot left (EpochGate itself)
|
||||
* @warning EpochGate is assumed to sit in the Epoch's first slot
|
||||
*/
|
||||
EpochGate()
|
||||
: Activity{int(0), Time::ANYTIME}
|
||||
{
|
||||
// initialise allocation usage marker: start at last usable slot
|
||||
next = this + (Epoch::SIZ() - 1);
|
||||
ENSURE (next != this);
|
||||
}
|
||||
// default copyable
|
||||
|
||||
Instant&
|
||||
deadline()
|
||||
{
|
||||
return data_.condition.dead;
|
||||
}
|
||||
|
||||
bool
|
||||
isAlive (Time deadline)
|
||||
{
|
||||
/////////////////////////////////////////////OOO preliminary implementation ... should use the GATE-Activity itself
|
||||
return this->deadline() > deadline;
|
||||
}
|
||||
|
||||
size_t
|
||||
filledSlots() const
|
||||
{
|
||||
const Activity* firstAllocPoint{this + (Epoch::SIZ()-1)};
|
||||
return firstAllocPoint - next;
|
||||
}
|
||||
|
||||
bool
|
||||
hasFreeSlot() const
|
||||
{ // see C++ § 5.9 : comparison of pointers within same array
|
||||
return next > this;
|
||||
}
|
||||
|
||||
Activity*
|
||||
claimNextSlot()
|
||||
{
|
||||
REQUIRE (hasFreeSlot());
|
||||
return next--;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
EpochGate& gate() { return static_cast<EpochGate&> ((*this)[0]); }
|
||||
Time deadline() { return Time{gate().deadline()}; }
|
||||
|
||||
double
|
||||
getFillFactor()
|
||||
{
|
||||
return double(gate().filledSlots()) / (SIZ()-1);
|
||||
}
|
||||
|
||||
|
||||
static Epoch&
|
||||
implantInto (RawIter storageSlot)
|
||||
{
|
||||
Epoch& target = static_cast<Epoch&> (*storageSlot);
|
||||
new(&target[0]) EpochGate{};
|
||||
return target;
|
||||
}
|
||||
|
||||
static Epoch&
|
||||
setup (RawIter storageSlot, Time deadline)
|
||||
{
|
||||
Epoch& newEpoch{implantInto (storageSlot)};
|
||||
newEpoch.gate().deadline() = deadline;
|
||||
return newEpoch;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
}//(End)namespace blockFlow
|
||||
|
||||
template<class CONF>
|
||||
class FlowDiagnostic;
|
||||
|
||||
/**
|
||||
* Allocation Extent holding _scheduler Activities_ to be performed altogether
|
||||
* before a common _deadline._ Other than the underlying raw Extent, the Epoch
|
||||
* maintains a deadline time and keeps track of storage slots already claimed.
|
||||
* This is achieved by using the Activity record in the first slot as a GATE term
|
||||
* to maintain those administrative information.
|
||||
* @remark rationale is to discard the Extent as a whole, once deadline passed.
|
||||
*/
|
||||
class Epoch
|
||||
: public Allocator::Extent
|
||||
{
|
||||
|
||||
/// @warning will be faked, never constructed
|
||||
Epoch() = delete;
|
||||
|
||||
public:
|
||||
/**
|
||||
* specifically rigged GATE Activity,
|
||||
* used for managing Epoch metadata
|
||||
* - the Condition::rest tracks pending async IO operations
|
||||
* - the Condition::deadline is the nominal deadline of this Epoch
|
||||
* - the field `next` points to the next free allocation Slot to use
|
||||
*/
|
||||
struct EpochGate
|
||||
: Activity
|
||||
{
|
||||
/** @note initially by default there is...
|
||||
* - effectively no deadline
|
||||
* - no IO operations pending (i.e. we can just discard the Epoch)
|
||||
* - the `next` usable Slot is the last Storage slot, and will be
|
||||
* decremented until there is only one slot left (EpochGate itself)
|
||||
* @warning EpochGate is assumed to sit in the Epoch's first slot
|
||||
*/
|
||||
EpochGate()
|
||||
: Activity{int(0), Time::ANYTIME}
|
||||
{
|
||||
// initialise allocation usage marker: start at last usable slot
|
||||
next = this + (Epoch::SIZ() - 1);
|
||||
ENSURE (next != this);
|
||||
}
|
||||
// default copyable
|
||||
|
||||
Instant&
|
||||
deadline()
|
||||
{
|
||||
return data_.condition.dead;
|
||||
}
|
||||
|
||||
bool
|
||||
isAlive (Time deadline)
|
||||
{
|
||||
/////////////////////////////////////////////OOO preliminary implementation ... should use the GATE-Activity itself
|
||||
return this->deadline() > deadline;
|
||||
}
|
||||
|
||||
size_t
|
||||
filledSlots() const
|
||||
{
|
||||
const Activity* firstAllocPoint{this + (Epoch::SIZ()-1)};
|
||||
return firstAllocPoint - next;
|
||||
}
|
||||
|
||||
bool
|
||||
hasFreeSlot() const
|
||||
{ // see C++ § 5.9 : comparison of pointers within same array
|
||||
return next > this;
|
||||
}
|
||||
|
||||
Activity*
|
||||
claimNextSlot()
|
||||
{
|
||||
REQUIRE (hasFreeSlot());
|
||||
return next--;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
EpochGate& gate() { return static_cast<EpochGate&> ((*this)[0]); }
|
||||
Time deadline() { return Time{gate().deadline()}; }
|
||||
|
||||
double
|
||||
getFillFactor()
|
||||
{
|
||||
return double(gate().filledSlots()) / (SIZ()-1);
|
||||
}
|
||||
|
||||
|
||||
static Epoch&
|
||||
implantInto (Allocator::iterator storageSlot)
|
||||
{
|
||||
Epoch& target = static_cast<Epoch&> (*storageSlot);
|
||||
new(&target[0]) EpochGate{};
|
||||
return target;
|
||||
}
|
||||
|
||||
static Epoch&
|
||||
setup (Allocator::iterator storageSlot, Time deadline)
|
||||
{
|
||||
Epoch& newEpoch{implantInto (storageSlot)};
|
||||
newEpoch.gate().deadline() = deadline;
|
||||
return newEpoch;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
|
@ -283,25 +341,37 @@ namespace gear {
|
|||
* @see SchedulerCommutator
|
||||
* @see BlockFlow_test
|
||||
*/
|
||||
template<class CONF = blockFlow::DefaultConfig>
|
||||
class BlockFlow
|
||||
: util::NonCopyable
|
||||
: public blockFlow::Strategy<CONF>
|
||||
, util::NonCopyable
|
||||
{
|
||||
constexpr static size_t EPOCH_SIZ = CONF::EPOCH_SIZ;
|
||||
|
||||
public:
|
||||
using Allocator = mem::ExtentFamily<Activity, EPOCH_SIZ>;
|
||||
using RawIter = typename Allocator::iterator;
|
||||
using Extent = typename Allocator::Extent;
|
||||
using Epoch = blockFlow::Epoch<Allocator>;
|
||||
|
||||
|
||||
private:
|
||||
Allocator alloc_;
|
||||
TimeVar epochStep_;
|
||||
|
||||
|
||||
/** @internal use a raw storage Extent as Epoch (unchecked cast) */
|
||||
static Epoch&
|
||||
asEpoch (Allocator::Extent& extent)
|
||||
asEpoch (Extent& extent)
|
||||
{
|
||||
return static_cast<Epoch&> (extent);
|
||||
}
|
||||
|
||||
struct StorageAdaptor : Allocator::iterator
|
||||
struct StorageAdaptor : RawIter
|
||||
{
|
||||
StorageAdaptor() = default;
|
||||
StorageAdaptor(Allocator::iterator it) : Allocator::iterator{it} { }
|
||||
Epoch& yield() const { return asEpoch (Allocator::iterator::yield()); }
|
||||
StorageAdaptor(RawIter it) : RawIter{it} { }
|
||||
Epoch& yield() const { return asEpoch (RawIter::yield()); }
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -347,7 +417,7 @@ namespace gear {
|
|||
BlockFlow* flow_;
|
||||
|
||||
public:
|
||||
AllocatorHandle(Allocator::iterator slot, BlockFlow* parent)
|
||||
AllocatorHandle(RawIter slot, BlockFlow* parent)
|
||||
: epoch_{slot}
|
||||
, flow_{parent}
|
||||
{ }
|
||||
|
|
@ -570,7 +640,7 @@ namespace gear {
|
|||
|
||||
|
||||
/// „backdoor“ to watch internals from tests
|
||||
friend class FlowDiagnostic;
|
||||
friend class FlowDiagnostic<CONF>;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -582,12 +652,15 @@ namespace gear {
|
|||
|
||||
/* ===== Test / Diagnostic ===== */
|
||||
|
||||
template<class CONF>
|
||||
class FlowDiagnostic
|
||||
{
|
||||
BlockFlow& flow_;
|
||||
using Epoch = typename BlockFlow<CONF>::Epoch;
|
||||
|
||||
BlockFlow<CONF>& flow_;
|
||||
|
||||
public:
|
||||
FlowDiagnostic(BlockFlow& theFlow)
|
||||
FlowDiagnostic(BlockFlow<CONF>& theFlow)
|
||||
: flow_{theFlow}
|
||||
{ }
|
||||
|
||||
|
|
@ -618,8 +691,9 @@ namespace gear {
|
|||
}
|
||||
};
|
||||
|
||||
inline FlowDiagnostic
|
||||
watch (BlockFlow& theFlow)
|
||||
template<class CONF>
|
||||
inline FlowDiagnostic<CONF>
|
||||
watch (BlockFlow<CONF>& theFlow)
|
||||
{
|
||||
return FlowDiagnostic{theFlow};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,6 +57,13 @@ namespace test {
|
|||
|
||||
// using lib::time::FrameRate;
|
||||
// using lib::time::Time;
|
||||
namespace {
|
||||
using BlockFlow = gear::BlockFlow<>;
|
||||
using Extent = BlockFlow::Extent;
|
||||
using Epoch = BlockFlow::Epoch;
|
||||
|
||||
const size_t EXTENT_SIZ = Extent::SIZ();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -117,7 +124,6 @@ namespace test {
|
|||
void
|
||||
handleEpoch()
|
||||
{
|
||||
using Extent = Allocator::Extent;
|
||||
// the raw storage Extent is a compact block
|
||||
// providing uninitialised storage typed as `vault::gear::Activity`
|
||||
|
||||
|
|
@ -172,7 +178,7 @@ namespace test {
|
|||
CHECK (1 == gate.filledSlots());
|
||||
CHECK (gate.hasFreeSlot());
|
||||
|
||||
CHECK (epoch.getFillFactor() == double(gate.filledSlots()) / (Epoch::SIZ()-1));
|
||||
CHECK (epoch.getFillFactor() == double(gate.filledSlots()) / (EXTENT_SIZ-1));
|
||||
|
||||
// so let's eat this space up...
|
||||
for (uint i=extent.size()-2; i>1; --i)
|
||||
|
|
@ -180,14 +186,14 @@ namespace test {
|
|||
|
||||
// one final slot is left (beyond of the EpochGate itself)
|
||||
CHECK (isSameObject (*gate.next, epoch[1]));
|
||||
CHECK (gate.filledSlots() == Epoch::SIZ()-2);
|
||||
CHECK (gate.filledSlots() == EXTENT_SIZ-2);
|
||||
CHECK (gate.hasFreeSlot());
|
||||
|
||||
gate.claimNextSlot();
|
||||
// aaand the boat is full...
|
||||
CHECK (not gate.hasFreeSlot());
|
||||
CHECK (isSameObject (*gate.next, epoch[0]));
|
||||
CHECK (gate.filledSlots() == Epoch::SIZ()-1);
|
||||
CHECK (gate.filledSlots() == EXTENT_SIZ-1);
|
||||
CHECK (epoch.getFillFactor() == 1);
|
||||
|
||||
// a given Epoch can be checked for relevance against a deadline
|
||||
|
|
@ -245,7 +251,7 @@ namespace test {
|
|||
|
||||
// provoke Epoch overflow by exhausting all available storage slots
|
||||
BlockFlow::AllocatorHandle allocHandle = bFlow.until(Time{300,10});
|
||||
for (uint i=1; i<Epoch::SIZ(); ++i)
|
||||
for (uint i=1; i<EXTENT_SIZ; ++i)
|
||||
allocHandle.create();
|
||||
|
||||
CHECK (allocHandle.currDeadline() == Time(400,10));
|
||||
|
|
@ -258,7 +264,7 @@ namespace test {
|
|||
CHECK (watch(bFlow).find(a4) == "10s600ms"_expect);
|
||||
|
||||
// fill up and exhaust this Epoch too....
|
||||
for (uint i=1; i<Epoch::SIZ(); ++i)
|
||||
for (uint i=1; i<EXTENT_SIZ; ++i)
|
||||
allocHandle.create();
|
||||
|
||||
// so the handle has moved to the after next Epoch
|
||||
|
|
@ -271,7 +277,7 @@ namespace test {
|
|||
|
||||
// now repeat the same pattern, but now towards uncharted Epochs
|
||||
allocHandle = bFlow.until(Time{900,10});
|
||||
for (uint i=2; i<Epoch::SIZ(); ++i)
|
||||
for (uint i=2; i<EXTENT_SIZ; ++i)
|
||||
allocHandle.create();
|
||||
|
||||
CHECK (allocHandle.currDeadline() == Time(0,11));
|
||||
|
|
|
|||
|
|
@ -80234,9 +80234,10 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node CREATED="1689809584696" ID="ID_1801960603" MODIFIED="1689809593344" TEXT="bisher war alles einfach in einem anonymen Namespace"/>
|
||||
<node CREATED="1689809593860" ID="ID_516321085" MODIFIED="1689809604951" TEXT="und dort war auch ein Typ "Allocator" definiert"/>
|
||||
</node>
|
||||
<node CREATED="1689809607614" ID="ID_236289241" MODIFIED="1689809624139" TEXT="Ansatz: policy-Mix-In">
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1689809625112" ID="ID_1243565823" MODIFIED="1689809788462" TEXT="wird in einem sub-Namespace blockFlow bereitgestellt">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#435e98" CREATED="1689809607614" ID="ID_236289241" MODIFIED="1689872669620" TEXT="Ansatz: policy-Mix-In">
|
||||
<icon BUILTIN="idea"/>
|
||||
<node COLOR="#435e98" CREATED="1689809625112" ID="ID_1243565823" MODIFIED="1689872637282" TEXT="wird in einem sub-Namespace blockFlow bereitgestellt">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1689809792157" ID="ID_1564252749" MODIFIED="1689809807279" TEXT="DefaultConfig">
|
||||
<node CREATED="1689809818314" ID="ID_1792198273" MODIFIED="1689809823013" TEXT="als default-Argument"/>
|
||||
<node CREATED="1689809827345" ID="ID_81051745" MODIFIED="1689809834680" TEXT="wird für die Tests verwendet">
|
||||
|
|
@ -80245,10 +80246,10 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
<node CREATED="1689809808051" ID="ID_649095088" MODIFIED="1689809811895" TEXT="RenderConfig"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1689809665379" ID="ID_1833888873" MODIFIED="1689809754826" TEXT="per Template-Parameter eingemischt">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1689809665379" ID="ID_1833888873" MODIFIED="1689872648583" TEXT="per Template-Parameter eingemischt">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1689810756996" ID="ID_97852927" MODIFIED="1689810767657" TEXT="soll Konfigurierbarkeit schaffen"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1689810768845" ID="ID_1900574250" MODIFIED="1689860411216" TEXT="Konsequenz ⟹ muß eine Strategy abspalten">
|
||||
<node COLOR="#435e98" CREATED="1689810768845" ID="ID_1900574250" MODIFIED="1689872627938" TEXT="Konsequenz ⟹ muß eine Strategy abspalten">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
|
|
@ -80258,8 +80259,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1689860417547" ID="ID_1858836680" MODIFIED="1689860435193" TEXT="Zugriff von dort auf die Config als Meyers Singleton">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1689860417547" ID="ID_1858836680" MODIFIED="1689872568369" TEXT="Zugriff von dort auf die Config als Meyers Singleton">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1689860436808" ID="ID_666663778" MODIFIED="1689863231116" TEXT="Diskussion...">
|
||||
<icon BUILTIN="info"/>
|
||||
<node CREATED="1689860443279" ID="ID_953236469" MODIFIED="1689861105486" TEXT="man könnte auch direkt die Felder non-static einmischen">
|
||||
|
|
@ -80303,29 +80304,28 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1689863244607" ID="ID_824360010" MODIFIED="1689863256431" TEXT="als Getter direkt in die Config-Klasse eingebaut">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1689863244607" ID="ID_824360010" MODIFIED="1689872622784" TEXT="als Getter in die Strategy-Basisklasse eingebaut">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node CREATED="1689863261456" ID="ID_824983335" MODIFIED="1689863270316" TEXT="damit per Typ auflösbar">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1689809675666" ID="ID_899609884" MODIFIED="1689809753618" TEXT="⟹ damit wird auch Epoch parametrisiert">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1689809757289" ID="ID_1758760519" MODIFIED="1689809785454" TEXT="und zwar auf den Allocator">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1689809675666" ID="ID_899609884" MODIFIED="1689872656941" TEXT="⟹ damit wird auch Epoch parametrisiert">
|
||||
<node COLOR="#338800" CREATED="1689809757289" ID="ID_1758760519" MODIFIED="1689872663074" TEXT="und zwar auf den Allocator">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1689809767024" ID="ID_263502473" MODIFIED="1689809784790" TEXT="der einfache Name Epoch wandert nun in BlockFlow">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1689809767024" ID="ID_263502473" MODIFIED="1689872663073" TEXT="der einfache Name Epoch wandert nun in BlockFlow">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1689818224323" ID="ID_1914141471" MODIFIED="1689818233142" TEXT="Strategy baut darauf auf">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1689818224323" ID="ID_1914141471" MODIFIED="1689872666750" TEXT="Strategy baut darauf auf">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1689818168020" ID="ID_745780964" MODIFIED="1689818211837" TEXT="Parameter reorganisieren">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1689818168020" ID="ID_745780964" MODIFIED="1689872676809" TEXT="Parameter reorganisieren">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1689818175388" ID="ID_1172559425" MODIFIED="1689818181757" TEXT="charakteristische Parameter"/>
|
||||
<node CREATED="1689818182227" ID="ID_385651938" MODIFIED="1689818185945" TEXT="Tuning-Parameter"/>
|
||||
<node CREATED="1689818186633" ID="ID_76340851" MODIFIED="1689818191732" TEXT="Kontext-Annahmen"/>
|
||||
|
|
@ -80867,6 +80867,17 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1689809417524" ID="ID_1054295274" MODIFIED="1689812997432" TEXT="setzt Umbau der Parametrisierung voraus">
|
||||
<arrowlink COLOR="#7a2dcb" DESTINATION="ID_469668336" ENDARROW="Default" ENDINCLINATION="-742;705;" ID="Arrow_ID_1498620407" STARTARROW="None" STARTINCLINATION="435;-802;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1689873255900" ID="ID_49309408" MODIFIED="1689873446639" TEXT="erst mal: Zugriff via Meyer's Singleton einführen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#435e98" CREATED="1689873426661" ID="ID_476877906" MODIFIED="1689873442030" TEXT="Parameter sollen sich im Default-Fall identisch ergeben">
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1689873270874" ID="ID_66965861" MODIFIED="1689873410951" TEXT="Laufzeiten">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1689873274593" ID="ID_116423794" MODIFIED="1689873404864" TEXT="-O0 : 630ns"/>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1689873396056" ID="ID_1088441301" MODIFIED="1689873404865" TEXT="-O3 : 46ns"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1689813003462" ID="ID_1047452990" MODIFIED="1689813037510" TEXT="vermutlich gibt es aber eine natürliche Obergrenze">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
|
|
|
|||
Loading…
Reference in a new issue