Workforce: draft simple usage
...start with an oversimplified implementation...
This commit is contained in:
parent
70cd8af806
commit
38ab5a6aa9
5 changed files with 76 additions and 13 deletions
|
|
@ -37,6 +37,7 @@
|
|||
#include "vault/gear/work-force.hpp"
|
||||
//#include "lib/symbol.hpp"
|
||||
//#include "include/logging.h"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
//#include <string>
|
||||
|
||||
|
|
@ -49,12 +50,15 @@ namespace gear {
|
|||
|
||||
namespace { // internal details
|
||||
|
||||
size_t MINIMAL_CONCURRENCY = 2;
|
||||
|
||||
} // internal details
|
||||
|
||||
|
||||
|
||||
// NA::~NA() { }
|
||||
|
||||
const size_t WorkForce::FULL_SIZE = util::max (std::thread::hardware_concurrency(), MINIMAL_CONCURRENCY);
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -37,11 +37,17 @@
|
|||
|
||||
|
||||
#include "vault/common.hpp"
|
||||
#include "vault/gear/activity.hpp"
|
||||
#include "lib/nocopy.hpp"
|
||||
//#include "lib/symbol.hpp"
|
||||
//#include "lib/util.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
//#include <string>
|
||||
#include <functional>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <thread>
|
||||
#include <atomic>
|
||||
|
||||
|
||||
namespace vault{
|
||||
|
|
@ -49,6 +55,8 @@ namespace gear {
|
|||
|
||||
// using util::isnil;
|
||||
// using std::string;
|
||||
using std::move;
|
||||
using std::atomic;
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -60,27 +68,69 @@ namespace gear {
|
|||
class WorkForce
|
||||
: util::NonCopyable
|
||||
{
|
||||
short nothing_;
|
||||
using WorkFun = std::function<activity::Proc(void)>;
|
||||
using Pool = std::vector<std::thread>;
|
||||
|
||||
WorkFun workFun_;
|
||||
Pool workers_;
|
||||
|
||||
atomic<bool> halt_{false};
|
||||
|
||||
public:
|
||||
template<typename FUN>
|
||||
static const size_t FULL_SIZE;
|
||||
|
||||
explicit
|
||||
WorkForce (FUN&& fun)
|
||||
: nothing_{42}
|
||||
{ }
|
||||
WorkForce (WorkFun&& fun)
|
||||
: workFun_{move (fun)}
|
||||
, workers_{}
|
||||
{
|
||||
workers_.reserve (1.5*FULL_SIZE);
|
||||
}
|
||||
|
||||
~WorkForce()
|
||||
{
|
||||
try {
|
||||
deactivate();
|
||||
}
|
||||
ERROR_LOG_AND_IGNORE (threadpool, "defunct worker thread")
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
activate (double degree =1.0)
|
||||
{
|
||||
UNIMPLEMENTED ("scale up");
|
||||
halt_ = false;
|
||||
size_t scale = util::max (size_t(degree*FULL_SIZE), 1u);
|
||||
for (uint i = workers_.size(); i < scale; ++i)
|
||||
workers_.emplace_back ([this]{ pullWork(); });
|
||||
}
|
||||
|
||||
void
|
||||
deactivate()
|
||||
{
|
||||
UNIMPLEMENTED ("scale down to halt");
|
||||
halt_ = true;
|
||||
for (auto& w : workers_)
|
||||
if (w.joinable())
|
||||
w.join();
|
||||
workers_.clear();
|
||||
}
|
||||
|
||||
private:
|
||||
void
|
||||
pullWork()
|
||||
{
|
||||
try {
|
||||
while (true)
|
||||
{
|
||||
activity::Proc res = workFun_();
|
||||
if (halt_ or res != activity::PASS)
|
||||
break;
|
||||
}
|
||||
}
|
||||
ERROR_LOG_AND_IGNORE (threadpool, "defunct worker thread")
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
#include "lib/test/run.hpp"
|
||||
#include "vault/gear/work-force.hpp"
|
||||
//#include "lib/time/timevalue.hpp"
|
||||
//#include "lib/format-cout.hpp"
|
||||
#include "lib/format-cout.hpp" ///////////////////////////////WIP
|
||||
//#include "lib/util.hpp"
|
||||
|
||||
//#include <utility>
|
||||
|
|
@ -75,9 +75,9 @@ namespace test {
|
|||
void
|
||||
simpleUsage()
|
||||
{
|
||||
uint check{0};
|
||||
atomic<uint> check{0};
|
||||
|
||||
WorkForce wof{[&]{ ++check; return true; }};
|
||||
WorkForce wof{[&]{ ++check; return activity::PASS; }};
|
||||
|
||||
CHECK (0 == check);
|
||||
|
||||
|
|
|
|||
|
|
@ -7167,14 +7167,14 @@ 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="202307272248" tags="Rendering spec draft" changecount="15">
|
||||
<div title="Scheduler" creator="Ichthyostega" modifier="Ichthyostega" created="202304140131" modified="202309042142" tags="Rendering spec draft" changecount="17">
|
||||
<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
|
||||
;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
|
||||
;Layer-1: Invocation
|
||||
:operates a low-level priority scheduling mechanism for time-bound execution of [[activities|RenderActivity]]
|
||||
:coordinates a ThreadPool and dispatches the execution of individual jobs into appropriate worker threads.
|
||||
|
||||
!Event based vs. time based operational control
|
||||
Time bound delivery of media data is an important aspect of editing and playback -- yet other concerns are of similar importance: the ability to make optimum use of scarce resources and to complete extended processing in reasonable time, while retaining some overall responsiveness of the system. And, especially for the //final render,// it is tantamount to produce 100% correct results without any glitches -- a goal that can not be reconciled with the demand for perfect timing. These considerations alone are sufficient to indicate, that strict adherence to a pre-established calculation plan is not enough to build a viable render engine. As far as media processing is concerned, the limited I/O bandwidth is the most precious resource -- reading and writing data from persistent storage requires a lot of time, with generally unpredictable timings, necessitating asynchronous processing.
|
||||
|
|
|
|||
|
|
@ -79627,6 +79627,15 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</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">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1693864792879" ID="ID_1957135454" MODIFIED="1693864812713" TEXT="lediglich einen Pool hochfahren">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1693864804725" ID="ID_197610779" MODIFIED="1693864812213" TEXT="verifizieren daß überhaupt etwas berechnet wird">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue