From f34ecafa1a1c9a905f2e7f13020a14c2f19278ae Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Thu, 6 Jul 2023 16:35:42 +0200 Subject: [PATCH] Block-Flow: consider data storage for render activities MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - decision to favour small memory footprint - rather use several Activity records to express invocation - design Activity record as »POD with constructor« - conceptually, Activity is polymorphic, but on implementation level, this is "folded down" into union-based data storage, layering accessor functions on top --- src/vault/gear/activity.hpp | 107 ++++++- src/vault/gear/scheduler-invocation.hpp | 4 +- tests/vault/gear/scheduler-activity-test.cpp | 8 +- wiki/renderengine.html | 19 +- wiki/thinkPad.ichthyo.mm | 297 ++++++++++++++++++- 5 files changed, 416 insertions(+), 19 deletions(-) diff --git a/src/vault/gear/activity.hpp b/src/vault/gear/activity.hpp index dd4634188..4a215fad3 100644 --- a/src/vault/gear/activity.hpp +++ b/src/vault/gear/activity.hpp @@ -47,6 +47,8 @@ #include "vault/common.hpp" +#include "vault/gear/job.h" +#include "lib/time/timevalue.hpp" //#include "lib/symbol.hpp" //#include "lib/util.hpp" @@ -56,33 +58,130 @@ namespace vault{ namespace gear { + using lib::time::TimeValue; + using lib::time::TimeVar; // using util::isnil; // using std::string; + /** + * Wrapper to hold Time values in trivially constructible union. + * By an unfortunate design decision, lib::time::Time values are + * non-copyable, which prevents placing them into POD data + * + * @todo 7/2023 this decision should be reverted //////////////////////////////////////////////////////////TICKET #1261 : reconsider (im)mutability of time entities + */ + class Instant + { + int64_t microTick_; + + public: + Instant() =default; // @suppress("Class members should be properly initialized") + + Instant(TimeValue time) + : microTick_{_raw(time)} + { } + + operator TimeVar() const + { + return TimeValue{microTick_}; + } + + // default copy acceptable + }; /** * Term to describe an Activity, * to happen within the Scheduler's control flow. + * @note Activity is a »POD with constructor« + * - trivially *destructible* + * - trivially *copyable* + * - standard layout */ class Activity { - public: - enum Verb {INVOKE ///< dispatches a JobFunctor into a worker thread - ,DEPEND ///< verify a given number of dependencies has been satisfied + /** All possible kinds of activities */ + enum Verb {INVOKE ///< dispatch a JobFunctor into a worker thread ,TIMESTART ///< signal start of some processing (for timing measurement) ,TIMESTOP ///< correspondingly signal end of some processing ,NOTIFY ///< push a message to another Activity - ,PROBE ///< evaluate a condition and inhibit another target Activity ,GATE ///< probe window + count-down; activate next Activity, else re-schedule + ,FEED ///< supply additional payload data for a preceding Activity + ,POST ///< post a message providing a chain of further time-bound Activities ,TICK ///< internal engine »heart beat« for internal maintenance hook(s) }; const Verb verb_; + /** + * Activities are organised into _chains_ + * to represent _relations_ based on verbs. + */ + Activity* next; + + + /* === Activity Data Arguments === */ + + /** Payload data to provide */ + struct Feed + { + size_t one; + size_t two; + }; + + /** Timing observation to propagate */ + struct Timing + { + Instant instant; + size_t quality; + }; + + /** Access gate condition to evaluate */ + struct Condition + { + int rest; ///< alive while rest > 0 + Instant dead; ///< alive while time < dead + }; + + /** Time window to define for activation */ + struct TimeWindow + { + Instant life; + Instant dead; + }; + + /** External work functor to activate */ + struct Invocation + { + JobFunctor* task; + Instant time; + }; + + /** Notification towards another Activity */ + struct Notification + { + Activity* target; + size_t report; + }; + + + /** Storage of Argument data dependent on Activity::verb_ */ + union ArgumentData + { + Feed feed; + Timing timing; + Condition condition; + TimeWindow timeWindow; + Invocation invocation; + Notification notification; + }; + ArgumentData data_; + + explicit Activity (Verb verb) : verb_{verb} + , next{nullptr} { } // using default copy/assignment diff --git a/src/vault/gear/scheduler-invocation.hpp b/src/vault/gear/scheduler-invocation.hpp index 6971adce4..724e23f97 100644 --- a/src/vault/gear/scheduler-invocation.hpp +++ b/src/vault/gear/scheduler-invocation.hpp @@ -62,8 +62,8 @@ namespace gear { /** * Scheduler Layer-2 : invocation. * - * @see SomeSystem - * @see NA_test + * @see Scheduler + * @see SchedulerInvocation_test */ class SchedulerInvocation : util::NonCopyable diff --git a/tests/vault/gear/scheduler-activity-test.cpp b/tests/vault/gear/scheduler-activity-test.cpp index ab3a3edd2..94d3bcbbf 100644 --- a/tests/vault/gear/scheduler-activity-test.cpp +++ b/tests/vault/gear/scheduler-activity-test.cpp @@ -39,7 +39,7 @@ using test::Test; namespace vault{ -namespace mem { +namespace gear { namespace test { // using lib::time::FrameRate; @@ -72,6 +72,10 @@ namespace test { void simpleUsage() { + // Activities are »POD with constructor« + Activity tick(Activity::TICK); + CHECK (tick.verb_ == Activity::TICK); + CHECK (tick.next == nullptr); } @@ -99,4 +103,4 @@ namespace test { -}}} // namespace vault::mem::test +}}} // namespace vault::gear::test diff --git a/wiki/renderengine.html b/wiki/renderengine.html index 7ab0a55d8..7efe39a4a 100644 --- a/wiki/renderengine.html +++ b/wiki/renderengine.html @@ -6853,7 +6853,7 @@ At first sight the link between asset and clip-MO is a simple logical relation b {{red{Note 1/2015}}} several aspects regarding the relation of clips and single/multichannel media are not yet settled. There is a preliminary implementation in the code base, but it is not sure yet how multichnnel media will actually be modelled. Currently, we tend to treat the channel multiplicity rather as a property of the involved media, i.e we have //one// clip object. -
+
//Render Activities define the execution language of the render engine.//
 The [[Scheduler]] maintains the ability to perform these Activities, in a time-bound fashion, observing dependency relations; activities allow for notification of completed work, tracking of dependencies, timing measurements, re-scheduling of other activities -- and last but not least the dispatch of actual [[render jobs|RenderJob]]. Activities are what is actually enqueued with priority in the scheduler implementation, they are planned for a »µ-tick slot«, activated once when the activation time is reached, and then forgotten. Each Activity is a //verb//, but can be inhibited by conditions and carry operation object data. Formally, activating an Activity equates to a predication, and the subject of that utterance is »the render process«.
 
@@ -6861,21 +6861,28 @@ The [[Scheduler]] maintains the ability to perform these Activities, in a time-b
 ;invoke
 :dispatches a JobFunctor into an appropriate worker thread, based on the job definition's execution spec
 :no further dependency checks; Activities attached to the job are re-dispatched after the job function's completion
-;depend
-:verify a given number of dependencies has been satisfied, otherwise inhibit the indicated target Activity
 ;timestart
 :signal start of some processing -- for the purpose of timing measurement, but also to detect crashed tasks
 ;timestop
 :correspondingly signal end of some processing
 ;notify
 :push a message to another Activity or process record
-;probe
-:invoke a closure within engine context; inhibit another target Activity, depending on the result.
 ;gate
 :probe a launch window [start…deadline[ and check a count-down latch ⟹activate next Activity | else re-schedule @self into the future
+;feed
+:supply additional payload data for a preceding Activity
+;post
+:post a message providing a chain of further time-bound Activities
 ;tick
 :internal engine »heart beat« -- invoke internal maintenance hook(s)
- 
+ +!Data organisation +Activities are processed within a //performance critical part of the application// -- and are thus subject to [[Scheduler memory management|SchedulerMemory]]. +While Activities are logically polymorphic, they are implemented as »POD with constructor« -- meaning that they are classes with [[standard layout|https://en.cppreference.com/w/cpp/named_req/StandardLayoutType]] and at least a [[trivial destructor|https://en.cppreference.com/w/cpp/language/destructor#Trivial_destructor]], allowing to just place them into a memory block and forget about them (without need to call any non-trivial functions). The ''Argument data'' depends on the //actual verb// and is thus placed into a union, with access functions to ensure proper usage of the data fields (while it is always possible to access the data field directly). Since Activities are allocated a lot, small memory footprint is favoured, and thus some significant information -- notably the //time window// for activation of each Activity -- is defined //contextually.// + +Activities are organised into ''chains'', allowing to express relations based on their respective verbs. +There are //standard usage patters,// hard coded into the {{{ActivityLang}}} and expected by the {{{SchedulerCommutator}}}, to express all relevant patterns of operational logic necessary to represent time-bound and dependent playback and render tasks. +
//the active core of each [[calculation stream|CalcStream]]//
diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm
index b278c277e..1e5a7e59b 100644
--- a/wiki/thinkPad.ichthyo.mm
+++ b/wiki/thinkPad.ichthyo.mm
@@ -74659,6 +74659,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ @@ -76539,7 +76540,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + + @@ -77462,6 +77464,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ @@ -77644,7 +77647,38 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + + + + + + + + + + + + + + + + +

+ werden vom jeweiligen Funktor flexibel interpretiert (ggfs auch als + void*); der wichtigste Funktor ist der für das eigentliche Rendern �� + dieser speichert hier die ExitNode und das DataSink +

+ +
+ + + + + + + + +
@@ -77835,6 +77869,31 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + +

+ supply additional payload data for a preceding Activity +

+ +
+
+ + + + + + +

+ post a message providing a chain of further time-bound Activities +

+ +
+ +
@@ -77853,7 +77912,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- +
@@ -77878,6 +77937,112 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ startTime +

+

+ deadline +

+ +
+ + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ Richtwert: 2 * 64bit + next-Ptr +

+ +
+ +
+
+
@@ -78295,7 +78460,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -78701,7 +78866,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -78767,6 +78932,13 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + +
@@ -84010,6 +84182,121 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + + + + + + + + + + + + + + +

+ wenn ein Member eine nichttriviale Funktion hat, +

+

+ dann muß die gleiche Funktion für die unition explizit geschrieben werden +

+
    +
  • + ctor (auch default) +
  • +
  • + copy-ctor +
  • +
  • + assignment +
  • +
  • + dtor +
  • +
  • + vtable +
  • +
+ +
+ +
+
+ + + + + + +

+ im Zweifelsfall: std::is_pod<TY>() fragen +

+ +
+ +
+ + + + + + +

+ Achtung: der Begriff »POD« is @deprecated +

+ +
+ + + + + + + + + + + + + + + + + + +

+ „trivial“ ⟹ der Compiler muß nix Spezielles  machen +

+ +
+ +
+ + + + + + + + + + + + + + + + + +
+