Workforce: implementation complete
This commit is contained in:
parent
397ded86df
commit
997fc36c81
7 changed files with 153 additions and 72 deletions
|
|
@ -23,12 +23,29 @@
|
|||
|
||||
/** @file work-force.hpp
|
||||
** A pool of workers for multithreaded rendering.
|
||||
** The Lumiera Render Engine is driven by active workers repeatedly pulling
|
||||
** the next planned chunk of work; maintaining the internal organisation of the
|
||||
** Scheduler is integrated into that pattern as _just another activity_ performed
|
||||
** by the workers. As a consequence, there is no need for a central »master« or
|
||||
** coordinator to dispatch individual jobs. As long as the worker pool holds
|
||||
** active workers, the engine is in running state.
|
||||
**
|
||||
** The WorkForce (worker pool service) in turn is passive and fulfils the purpose of
|
||||
** holding storage for the active worker objects in a list, pruning terminated entries.
|
||||
** Some parameters and configuration is provided to the workers, notably a _work functor_
|
||||
** invoked actively to »pull« work. The return value from this `doWork()`-function governs
|
||||
** the worker's behaviour, either by prompting to pull further work, by sending a worker
|
||||
** into a sleep cycle, or even asking the worker to terminate.
|
||||
**
|
||||
** @warning concurrency and synchronisation in the Scheduler (which maintains and operates
|
||||
** WorkForce) is based on the assumption that _all maintenance and organisational
|
||||
** work is done chunk-wise by a single worker._ Other render activities may proceed
|
||||
** in parallel, yet any other worker about to pick the next task has to wait until
|
||||
** it is possible to grab the `GroomingToken` exclusively. For the WorkForce this
|
||||
** usage pattern implies that there is *no explicit synchronisation* -- scaling up
|
||||
** and shutting down must be performed non-concurrent.
|
||||
** @see work-force-test.cpp
|
||||
** @see scheduler-commutator.hpp usage as part of the scheduler
|
||||
**
|
||||
** @todo WIP-WIP-WIP 6/2023 »Playback Vertical Slice«
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
|
|
@ -40,11 +57,8 @@
|
|||
#include "vault/gear/activity.hpp"
|
||||
#include "lib/meta/function.hpp"
|
||||
#include "lib/nocopy.hpp"
|
||||
//#include "lib/symbol.hpp"
|
||||
#include "lib/util.hpp"
|
||||
#include "lib/format-cout.hpp"////////////////////WIP
|
||||
|
||||
//#include <string>
|
||||
#include <utility>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
|
@ -55,21 +69,17 @@
|
|||
namespace vault{
|
||||
namespace gear {
|
||||
|
||||
// using util::isnil;
|
||||
// using std::string;
|
||||
using std::move;
|
||||
// using std::forward;
|
||||
using std::atomic;
|
||||
using util::unConst;
|
||||
|
||||
|
||||
|
||||
namespace work {
|
||||
namespace work { ///< Details of WorkForce (worker pool) implementation
|
||||
using std::chrono::milliseconds;
|
||||
using std::chrono_literals::operator ""ms;
|
||||
|
||||
using SIG_WorkFun = activity::Proc(void); ///< config should define callable to perform work
|
||||
using SIG_FinalHook = void(bool); ///< config should define callable invoked at exit (argument: is error)
|
||||
using SIG_WorkFun = activity::Proc(void); ///< config should define a callable with this signature to perform work
|
||||
using SIG_FinalHook = void(bool); ///< config should define callable invoked at exit (argument: isFailure)
|
||||
|
||||
/**
|
||||
* Base for configuration of the worker pool.
|
||||
|
|
@ -90,7 +100,10 @@ namespace gear {
|
|||
};
|
||||
|
||||
|
||||
/** Individual worker thread: repeatedly pulls the `doWork` functor */
|
||||
/**
|
||||
* Individual worker thread:
|
||||
* repeatedly pulls the `doWork` functor.
|
||||
*/
|
||||
template<class CONF>
|
||||
class Runner
|
||||
: CONF
|
||||
|
|
@ -160,9 +173,9 @@ namespace gear {
|
|||
|
||||
|
||||
|
||||
/*************************************//**
|
||||
/***********************************************************//**
|
||||
* Pool of worker threads for rendering.
|
||||
* @note the \tparam CONF configuration/policy base must define
|
||||
* @note the \tparam CONF configuration/policy base must define:
|
||||
* - `doWork` - the _work-functor_ (with #SIG_WorkFun)
|
||||
* - `finalHook` - called at thread exit
|
||||
* @see WorkForce_test
|
||||
|
|
@ -196,7 +209,7 @@ namespace gear {
|
|||
/**
|
||||
* Activate or scale up the worker pool.
|
||||
* @param degree fraction of the full #COMPUTATION_CAPACITY to activate
|
||||
* @note will always activate at least one worker;
|
||||
* @note will always activate at least one worker; will never scale down;
|
||||
* setting values > 1.0 leads to over-provisioning...
|
||||
*/
|
||||
void
|
||||
|
|
|
|||
|
|
@ -38,6 +38,6 @@ END
|
|||
|
||||
|
||||
|
||||
PLANNED "Worker Thread Service" WorkForce_test <<END
|
||||
TEST "Worker Thread Service" WorkForce_test <<END
|
||||
return: 0
|
||||
END
|
||||
|
|
|
|||
|
|
@ -99,4 +99,4 @@ namespace test {
|
|||
|
||||
|
||||
|
||||
}}} // namespace vault::mem::test
|
||||
}}} // namespace vault::gear::test
|
||||
|
|
|
|||
|
|
@ -99,4 +99,4 @@ namespace test {
|
|||
|
||||
|
||||
|
||||
}}} // namespace vault::mem::test
|
||||
}}} // namespace vault::gear::test
|
||||
|
|
|
|||
|
|
@ -27,20 +27,14 @@
|
|||
|
||||
#include "lib/test/run.hpp"
|
||||
#include "vault/gear/work-force.hpp"
|
||||
//#include "lib/time/timevalue.hpp"
|
||||
//#include "lib/format-cout.hpp" ///////////////////////////////WIP
|
||||
#include "lib/test/diagnostic-output.hpp" ///////////////////////////////WIP
|
||||
//#include "lib/util.hpp"
|
||||
#include "lib/sync.hpp"
|
||||
|
||||
//#include <utility>
|
||||
//#include <chrono>
|
||||
#include <functional>
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
#include <set>
|
||||
|
||||
using test::Test;
|
||||
//using std::move;
|
||||
//using util::isSameObject;
|
||||
|
||||
|
||||
namespace vault{
|
||||
|
|
@ -51,14 +45,16 @@ namespace test {
|
|||
using namespace std::chrono_literals;
|
||||
using std::chrono::milliseconds;
|
||||
|
||||
// using lib::time::FrameRate;
|
||||
// using lib::time::Offset;
|
||||
// using lib::time::Time;
|
||||
|
||||
namespace {
|
||||
using WorkFun = std::function<work::SIG_WorkFun>;
|
||||
using FinalFun = std::function<work::SIG_FinalHook>;
|
||||
|
||||
/**
|
||||
* Helper: setup a Worker-Pool configuration for the test.
|
||||
* Derived from the default configuration, it allows to bind
|
||||
* a lambda as work-functor and to tweak other parameters.
|
||||
*/
|
||||
template<class FUN>
|
||||
auto
|
||||
setup (FUN&& workFun)
|
||||
|
|
@ -108,6 +104,7 @@ namespace test {
|
|||
|
||||
/*************************************************************************//**
|
||||
* @test WorkForce-Service: maintain a pool of active worker threads.
|
||||
* @warning this test relies on empirical timings and can be brittle.
|
||||
* @see SchedulerUsage_test
|
||||
*/
|
||||
class WorkForce_test : public Test
|
||||
|
|
@ -138,13 +135,13 @@ namespace test {
|
|||
{
|
||||
atomic<uint> check{0};
|
||||
WorkForce wof{setup ([&]{ ++check; return activity::PASS; })};
|
||||
|
||||
// ^^^ this is the doWork-λ
|
||||
CHECK (0 == check);
|
||||
|
||||
wof.activate();
|
||||
sleep_for(20ms);
|
||||
|
||||
CHECK (0 < check);
|
||||
CHECK (0 < check); // λ invoked in the worker threads
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -206,7 +203,7 @@ namespace test {
|
|||
|
||||
|
||||
|
||||
/** @test a worker can be sent to sleep, reducing the poll frequency.
|
||||
/** @test a worker can be sent to sleep, throttling the poll frequency.
|
||||
*/
|
||||
void
|
||||
verify_workerSleep()
|
||||
|
|
@ -230,7 +227,7 @@ namespace test {
|
|||
|
||||
|
||||
/** @test when a worker is sent into sleep-cycles for an extended time,
|
||||
* the worker terminates itself
|
||||
* the worker terminates itself.
|
||||
*/
|
||||
void
|
||||
verify_workerDismiss()
|
||||
|
|
@ -260,28 +257,29 @@ namespace test {
|
|||
void
|
||||
verify_finalHook()
|
||||
{
|
||||
atomic<uint> check{0};
|
||||
atomic<uint> exited{0};
|
||||
atomic<activity::Proc> control{activity::PASS};
|
||||
WorkForce wof{setup([&]{ return activity::Proc(control); })
|
||||
.withFinalHook([&](bool){ ++check; })};
|
||||
.withFinalHook([&](bool){ ++exited; })};
|
||||
|
||||
CHECK (0 == check);
|
||||
CHECK (0 == exited);
|
||||
|
||||
wof.activate();
|
||||
sleep_for(10ms);
|
||||
CHECK (wof.size() == work::Config::COMPUTATION_CAPACITY);
|
||||
CHECK (0 == check);
|
||||
CHECK (0 == exited);
|
||||
|
||||
control = activity::HALT;
|
||||
sleep_for(10ms);
|
||||
CHECK (0 == wof.size());
|
||||
CHECK (check == work::Config::COMPUTATION_CAPACITY);
|
||||
CHECK (exited == work::Config::COMPUTATION_CAPACITY);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** @test TODO
|
||||
* @todo WIP 9/23 ⟶ define ⟶ implement
|
||||
/** @test exceptions emanating from within the worker are catched
|
||||
* and reported by setting the isFailure argument flag of
|
||||
* the `finalHook` functor invoked at worker termination.
|
||||
*/
|
||||
void
|
||||
verify_detectError()
|
||||
|
|
@ -298,7 +296,6 @@ namespace test {
|
|||
if (isFailure)
|
||||
++errors;
|
||||
})};
|
||||
|
||||
CHECK (0 == check);
|
||||
CHECK (0 == errors);
|
||||
|
||||
|
|
@ -308,7 +305,7 @@ namespace test {
|
|||
|
||||
sleep_for(10us);
|
||||
CHECK (3 == wof.size());
|
||||
CHECK (0 < check);
|
||||
CHECK (0 < check);
|
||||
CHECK (0 == errors);
|
||||
|
||||
sleep_for(200ms); // wait for the programmed disaster
|
||||
|
|
@ -342,12 +339,75 @@ namespace test {
|
|||
|
||||
|
||||
|
||||
/** @test TODO
|
||||
* @todo WIP 9/23 ⟶ define ⟶ implement
|
||||
/** @test the number of (separate) workers can be scaled up,
|
||||
* both stepwise and as fraction of full hardware concurrency
|
||||
*/
|
||||
void
|
||||
verify_scalePool()
|
||||
{
|
||||
/** helper to count distinct thread-IDs */
|
||||
class UniqueCnt
|
||||
: public std::set<std::thread::id>
|
||||
, public lib::Sync<>
|
||||
{
|
||||
public:
|
||||
void
|
||||
mark (std::thread::id const& tID)
|
||||
{
|
||||
Lock guard(this);
|
||||
this->insert(tID);
|
||||
}
|
||||
|
||||
operator size_t() const
|
||||
{
|
||||
Lock guard(this);
|
||||
return this->size();
|
||||
}
|
||||
}
|
||||
uniqueCnt;
|
||||
|
||||
WorkForce wof{setup ([&]{
|
||||
uniqueCnt.mark(std::this_thread::get_id());
|
||||
return activity::PASS;
|
||||
})};
|
||||
|
||||
CHECK (0 == uniqueCnt);
|
||||
CHECK (0 == wof.size());
|
||||
|
||||
wof.incScale();
|
||||
sleep_for(100us);
|
||||
CHECK (1 == uniqueCnt);
|
||||
CHECK (1 == wof.size());
|
||||
|
||||
wof.incScale();
|
||||
sleep_for(100us);
|
||||
CHECK (2 == uniqueCnt);
|
||||
CHECK (2 == wof.size());
|
||||
|
||||
|
||||
auto fullCnt = work::Config::COMPUTATION_CAPACITY;
|
||||
|
||||
wof.activate (1.0);
|
||||
sleep_for(1ms);
|
||||
CHECK (fullCnt == uniqueCnt);
|
||||
CHECK (fullCnt == wof.size());
|
||||
|
||||
wof.activate (2.0);
|
||||
sleep_for(1ms);
|
||||
CHECK (2*fullCnt == uniqueCnt);
|
||||
CHECK (2*fullCnt == wof.size());
|
||||
|
||||
wof.awaitShutdown();
|
||||
CHECK (0 == wof.size());
|
||||
|
||||
uniqueCnt.clear();
|
||||
sleep_for(1ms);
|
||||
CHECK (0 == uniqueCnt);
|
||||
|
||||
wof.activate (0.5);
|
||||
sleep_for(1ms);
|
||||
CHECK (fullCnt/2 == uniqueCnt);
|
||||
CHECK (fullCnt/2 == wof.size());
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -386,7 +446,7 @@ namespace test {
|
|||
* - use a work-functor which keeps all workers blocked
|
||||
* - start the WorkForce within a separate thread
|
||||
* - in this separate thread, cause the WorkForce destructor to be called
|
||||
* - in the outer (controlling thread) release the work-functor blocking
|
||||
* - in the test main thread release the work-functor blocking
|
||||
* - at this point, all workers return, detect shutdown and terminate
|
||||
*/
|
||||
void
|
||||
|
|
@ -435,5 +495,4 @@ namespace test {
|
|||
LAUNCHER (WorkForce_test, "unit engine");
|
||||
|
||||
|
||||
|
||||
}}} // namespace vault::mem::test
|
||||
}}} // namespace vault::gear::test
|
||||
|
|
|
|||
|
|
@ -7167,9 +7167,9 @@ Later on we expect a distinct __query subsystem__ to emerge, presumably embeddin
|
|||
|
||||
&rarr; QuantiserImpl</pre>
|
||||
</div>
|
||||
<div title="Scheduler" creator="Ichthyostega" modifier="Ichthyostega" created="202304140131" modified="202309042142" tags="Rendering spec draft" changecount="17">
|
||||
<div title="Scheduler" creator="Ichthyostega" modifier="Ichthyostega" created="202304140131" modified="202309101341" tags="Rendering spec draft" changecount="19">
|
||||
<pre>//Invoke and control the dependency and time based execution of [[render jobs|RenderJob]]//
|
||||
The Scheduler acts as the central hub in the implementation of the RenderEngine and coordinates the //processing resources// of the application. Regarding architecture, the Scheduler is located in the Vault-Layer and //running// the Scheduler is equivalent to activating the »Vault Subsystem«. An EngineFaçade acts as entrance point, providing high-level render services to other parts of the application: [[render jobs|RenderJob]] can be activated under various timing and dependency constraints. Internally, the implementation is segregated into two layers
|
||||
The Scheduler acts as the central hub in the implementation of the RenderEngine and coordinates the //processing resources// of the application. Regarding architecture, the Scheduler is located in the Vault-Layer and //running// the Scheduler is equivalent to activating the »Vault Subsystem«. An EngineFaçade acts as entrance point, providing high-level render services to other parts of the application: [[render jobs|RenderJob]] can be activated under various timing and dependency constraints. Internally, the implementation is organised into two layers:
|
||||
;Layer-2: Coordination
|
||||
:maintains a network of interconnected [[activities|RenderActivity]], tracks dependencies and observes timing constraints
|
||||
:coordinates a [[pool of active Workers|SchedulerWorker]] to dispatch the next activities
|
||||
|
|
@ -7245,7 +7245,7 @@ The primary scaling effects exploited to achieve this level of performance are t
|
|||
The way other parts of the system are built, requires us to obtain a guaranteed knowledge of some job's termination. It is possible to obtain that knowledge with some limited delay, but it nees to be absoultely reliable (violations leading to segfault). The requirements stated above assume this can be achieved through //jobs with guaranteed execution.// Alternatively we could consider installing specific callbacks -- in this case the scheduler itself has to guarantee the invocation of these callbacks, even if the corresponding job fails or is never invoked. It doesn't seem there is any other option.
|
||||
</pre>
|
||||
</div>
|
||||
<div title="SchedulerWorker" creator="Ichthyostega" modifier="Ichthyostega" created="202309041605" modified="202309061718" tags="Rendering spec draft" changecount="10">
|
||||
<div title="SchedulerWorker" creator="Ichthyostega" modifier="Ichthyostega" created="202309041605" modified="202309101338" tags="Rendering spec draft" changecount="11">
|
||||
<pre>The Scheduler //maintains a ''Work Force'' (a pool of workers) to perform the next [[render activities|RenderActivity]] continuously.//
|
||||
Each worker runs in a dedicated thread; the Activities are arranged in a way to avoid blocking those worker threads
|
||||
* IO operations are performed asynchronously {{red{planned as of 9/23}}}
|
||||
|
|
@ -7257,7 +7257,7 @@ This leads to a situation where it is more adequate to //distribute the scarce c
|
|||
|
||||
Moreover, the actual computation tasks, which can be parallelised, are at least by an order of magnitude more expensive than any administrative work for sorting tasks, checking dependencies and maintaining process state. This leads to a scheme where a worker first performs some »management work«, until encountering the next actual computation job, at which point the worker leaves the //management mode// and transitions into //concurrent work mode//. All workers are expected to be in work mode almost entirely most of the time, and thus we can expect not much contention between workers performing »management work« -- allowing to confine this management work to //single threaded operation,// thereby drastically reducing the complexity of management data structures and memory allocation.
|
||||
!!!Regulating workers
|
||||
The behaviour of individual workers is guided solely by the return-value flag from the work-functor. Consequently, no shared flags and no direct synchronisation whatsoever is required //within the {{{WorkForce}}} implementation.// -- notwithstanding the fact that the implementation //within the work-functor// obviously needs some concurrency coordination to produce these return values, since this the whole point is to invoke this functor concurrently. The following aspects of worker behaviour can be directed:
|
||||
The behaviour of individual workers is guided solely by the return-value flag from the work-functor. Consequently, no shared flags and no direct synchronisation whatsoever is required //within the {{{WorkForce}}} implementation.// -- notwithstanding the fact that the implementation //within the work-functor// obviously needs some concurrency coordination to produce these return values, since the whole point is to invoke this functor concurrently. The following aspects of worker behaviour can be directed:
|
||||
* returning {{{activity::PASS}}} instructs the worker to re-invoke the work-functor in the same thread immediately
|
||||
* returning {{{activity::WAIT}}} requests an //idle-wait cycle//
|
||||
* any other value, notably {{{activity::HALT}}} causes the worker to terminate
|
||||
|
|
|
|||
|
|
@ -79444,10 +79444,10 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1689170064181" HGAP="5" ID="ID_987966047" MODIFIED="1689170075605" TEXT="WorkForce zur Ausführung" VSHIFT="7">
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1689170064181" HGAP="5" ID="ID_987966047" MODIFIED="1694352926145" TEXT="WorkForce zur Ausführung" VSHIFT="7">
|
||||
<linktarget COLOR="#5f39b2" DESTINATION="ID_987966047" ENDARROW="Default" ENDINCLINATION="-1039;-52;" ID="Arrow_ID_818972822" SOURCE="ID_1537960830" STARTARROW="None" STARTINCLINATION="-609;73;"/>
|
||||
<linktarget COLOR="#5f39b2" DESTINATION="ID_987966047" ENDARROW="Default" ENDINCLINATION="-1039;-52;" ID="Arrow_ID_7965989" SOURCE="ID_1957090536" STARTARROW="None" STARTINCLINATION="-1231;87;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1689170081403" ID="ID_196314311" MODIFIED="1689171233757" TEXT="Technologie-Entscheidung">
|
||||
<linktarget COLOR="#694db0" DESTINATION="ID_196314311" ENDARROW="Default" ENDINCLINATION="-56;-43;" ID="Arrow_ID_814147501" SOURCE="ID_1688483414" STARTARROW="None" STARTINCLINATION="-394;72;"/>
|
||||
<linktarget COLOR="#b22e63" DESTINATION="ID_196314311" ENDARROW="Default" ENDINCLINATION="-1383;-51;" ID="Arrow_ID_134934445" SOURCE="ID_14638704" STARTARROW="None" STARTINCLINATION="-753;40;"/>
|
||||
|
|
@ -79526,13 +79526,17 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
<node CREATED="1693783675300" ID="ID_1818177401" MODIFIED="1693790461409" TEXT="Entscheidungen">
|
||||
<icon BUILTIN="forward"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1693783691433" ID="ID_279372215" MODIFIED="1693783750796" TEXT="Worker-Management selber bauen">
|
||||
<node COLOR="#435e98" CREATED="1693783691433" ID="ID_279372215" MODIFIED="1694352793330" TEXT="Worker-Management selber bauen">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1693783766735" ID="ID_912764109" MODIFIED="1693783781449" TEXT="und zwar in C++">
|
||||
<node CREATED="1693783781989" ID="ID_1709905837" MODIFIED="1693783798679" TEXT="wegen Atomics & Futures"/>
|
||||
<node CREATED="1693783810401" ID="ID_1691365318" MODIFIED="1693783825729" TEXT="wegen Funktoren und Typsicherheit"/>
|
||||
<node CREATED="1693783799406" ID="ID_516886484" MODIFIED="1693783805118" TEXT="wegen Portabilität"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1694352635754" ID="ID_839402509" MODIFIED="1694352907504" TEXT="als eigenständige Komponente">
|
||||
<arrowlink COLOR="#69db57" DESTINATION="ID_671611566" ENDARROW="Default" ENDINCLINATION="-836;-66;" ID="Arrow_ID_633013629" STARTARROW="None" STARTINCLINATION="-728;61;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1693787750689" ID="ID_1636630763" MODIFIED="1693787785090" TEXT="lib::Thread wird aufgegeben">
|
||||
<icon BUILTIN="yes"/>
|
||||
|
|
@ -79619,14 +79623,15 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node CREATED="1693792477807" ID="ID_5065581" MODIFIED="1693792530740" TEXT="Zyklus: pull work / check / sleep">
|
||||
<node CREATED="1693792715966" ID="ID_717442289" MODIFIED="1693792730000" TEXT="die "pull-work"-Funkton wird vom Scheduler-Layer-2 bereitgestellt"/>
|
||||
<node CREATED="1693792744114" ID="ID_1037530409" MODIFIED="1693792754452" TEXT="die Schlaf-Periode ist ein (steuer)-Parameter"/>
|
||||
<node CREATED="1693792760213" ID="ID_1223151647" MODIFIED="1693792767060" TEXT="ggfs leicht randomisiert">
|
||||
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1693792760213" ID="ID_1223151647" MODIFIED="1694304517016" TEXT="ggfs leicht randomisiert">
|
||||
<icon BUILTIN="hourglass"/>
|
||||
<node CREATED="1693792791729" ID="ID_649360495" MODIFIED="1693792804966" TEXT="Einschätzung: das genügt um Contention zu vermeiden"/>
|
||||
<node CREATED="1693792900758" ID="ID_1613781033" MODIFIED="1693792927222" TEXT="Vorraussetzung: Arbeitsphase >> Management-Phase"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1693952215256" ID="ID_532083956" MODIFIED="1693952226539" TEXT="Implementierung">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1693952215256" ID="ID_532083956" MODIFIED="1694304448282" TEXT="Implementierung">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#435e98" CREATED="1693952247831" ID="ID_1732680738" LINK="#ID_391262141" MODIFIED="1694096132122" TEXT="Work-Function möglichst inline aber statisch konfigurierbar">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
|
|
@ -79869,7 +79874,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
<node COLOR="#338800" CREATED="1694016459017" ID="ID_445172345" MODIFIED="1694222678966" TEXT="Funktionalität">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1694016464368" ID="ID_1059038394" MODIFIED="1694212930507" TEXT="statisch konfigurierbarer Work-Funktor">
|
||||
<node COLOR="#338800" CREATED="1694016464368" FOLDED="true" ID="ID_1059038394" MODIFIED="1694304430896" TEXT="statisch konfigurierbarer Work-Funktor">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#5b280f" CREATED="1694095251355" ID="ID_612425707" MODIFIED="1694095281878" TEXT="geht nicht ohne Laufzeit-Initialisierung">
|
||||
<icon BUILTIN="stop-sign"/>
|
||||
|
|
@ -80031,9 +80036,10 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1693841488183" HGAP="-2" ID="ID_671611566" MODIFIED="1693841514321" TEXT="WorkForce_test (Komponententest)" VSHIFT="-3">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1693864786768" ID="ID_1997885802" MODIFIED="1693864791553" TEXT="simple usage">
|
||||
<node COLOR="#338800" CREATED="1693841488183" HGAP="-2" ID="ID_671611566" MODIFIED="1694352907504" TEXT="WorkForce_test (Komponententest)" VSHIFT="-3">
|
||||
<linktarget COLOR="#69db57" DESTINATION="ID_671611566" ENDARROW="Default" ENDINCLINATION="-836;-66;" ID="Arrow_ID_633013629" SOURCE="ID_839402509" STARTARROW="None" STARTINCLINATION="-728;61;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1693864786768" FOLDED="true" ID="ID_1997885802" MODIFIED="1693864791553" TEXT="simple usage">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1693864792879" ID="ID_1957135454" MODIFIED="1693864812713" TEXT="lediglich einen Pool hochfahren">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
|
|
@ -80042,7 +80048,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1694098740892" ID="ID_1850596111" MODIFIED="1694222608888" TEXT="Worker-Verhalten">
|
||||
<node COLOR="#338800" CREATED="1694098740892" FOLDED="true" ID="ID_1850596111" MODIFIED="1694222608888" TEXT="Worker-Verhalten">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1694098758090" ID="ID_1594595049" MODIFIED="1694174633952" TEXT="verify_pullWork: führt den Work-Funktor wiederholt aus">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
|
|
@ -80065,15 +80071,15 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1694098957487" ID="ID_143578534" MODIFIED="1694099563792" TEXT="Pool-Verhalten">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1694098957487" FOLDED="true" ID="ID_143578534" MODIFIED="1694304440676" TEXT="Pool-Verhalten">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1694099014497" ID="ID_1877110298" MODIFIED="1694174681345" TEXT="verify_default">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1694174644528" ID="ID_1593779460" MODIFIED="1694174645476" TEXT="default macht nichts"/>
|
||||
<node CREATED="1694174646160" ID="ID_1907976760" MODIFIED="1694174679928" TEXT="activate() skaliert auf Anzahl cores hoch"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1694099055410" ID="ID_1489311533" MODIFIED="1694099565281" TEXT="verify_scaleUp">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1694099055410" ID="ID_1489311533" MODIFIED="1694304397431" TEXT="verify_scaleUp">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1694099029004" ID="ID_910692339" MODIFIED="1694099041032" TEXT="skaliert auf genau N worker"/>
|
||||
<node CREATED="1694099061344" ID="ID_758198253" MODIFIED="1694099067644" TEXT="skaliert um einen Worker hoch"/>
|
||||
</node>
|
||||
|
|
@ -90133,9 +90139,12 @@ class Something
|
|||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1680389032371" ID="ID_663979640" LINK="https://issues.lumiera.org/ticket/1285" MODIFIED="1680389054385" TEXT="#1285 draft integration of asynchronous IO with rendering">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1680561901447" ID="ID_1591114904" LINK="https://issues.lumiera.org/ticket/1298" MODIFIED="1684980824431" TEXT="#1298 Render Activity verbs">
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1680561901447" ID="ID_1591114904" LINK="https://issues.lumiera.org/ticket/1298" MODIFIED="1694354328390" TEXT="#1298 Render Activity verbs">
|
||||
<arrowlink COLOR="#fde0ca" DESTINATION="ID_1599285907" ENDARROW="Default" ENDINCLINATION="-762;53;" ID="Arrow_ID_744981346" STARTARROW="None" STARTINCLINATION="-1043;88;"/>
|
||||
<icon BUILTIN="flag-pink"/>
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1694354381837" ID="ID_663246616" MODIFIED="1694354395299" TEXT="#1319 define Activity-Term and invoke render Activities">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -90171,8 +90180,8 @@ class Something
|
|||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1680561745270" ID="ID_264248978" MODIFIED="1680561760037" TEXT="Video-Display-UI">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1680561751261" ID="ID_1799759884" MODIFIED="1680561760040" TEXT="Worker-Thradpool">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1680561751261" ID="ID_1799759884" MODIFIED="1694354420599" TEXT="Worker-Thradpool">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1689171353019" ID="ID_1923378280" MODIFIED="1689171356858" TEXT="Architektur">
|
||||
|
|
|
|||
Loading…
Reference in a new issue