diff --git a/src/lib/time/time.cpp b/src/lib/time/time.cpp index 1369160af..14d80367b 100644 --- a/src/lib/time/time.cpp +++ b/src/lib/time/time.cpp @@ -273,22 +273,39 @@ namespace time { * @remark rational numbers bear the danger to overflow for quite ordinary computations; * we stay away from the absolute maximum by an additional safety margin of 1/1000. */ - const uint RATE_LIMIT{std::numeric_limits::max() / 1000}; + const uint RATE_LIMIT{std::numeric_limits::max() / 1024}; /** * @internal helper to work around the limitations of `uint`. * @return a fractional number approximating the floating-point spec. - * @todo imposing a quite coarse limitation. If this turns out - * to be a problem: we can do better, use lib::reQuant (rational.hpp) + * @todo imposing a quite coarse limitation. If this turns out to be + * a problem: we can do better, use lib::reQuant (rational.hpp) */ boost::rational __framerate_approximation (double fps) { - double quantised{fabs(fps) * RATE_LIMIT}; + const double UPPER_LIMIT = int64_t(RATE_LIMIT*1024) << 31; + const int64_t HAZARD = util::ilog2(RATE_LIMIT); - uint num = uint(limited (1u, quantised + 0.5, 1000u*RATE_LIMIT)); - uint den = RATE_LIMIT; - return {num, den}; + double doo = limited (1.0, fabs(fps) * RATE_LIMIT + 0.5, UPPER_LIMIT); + int64_t boo(doo); + util::Rat quantised{boo + ,int64_t(RATE_LIMIT) + }; + + int64_t num = quantised.numerator(); + int64_t toxic = util::ilog2(abs(num)); + toxic = util::max (0, toxic - HAZARD); + + int64_t base = quantised.denominator(); + if (toxic) + { + base = util::max (base >> toxic, 1); + num = util::reQuant (num, quantised.denominator(), base); + } + return {limited (1u, num, RATE_LIMIT) + ,limited (1u, base, RATE_LIMIT) + }; } /** @@ -300,7 +317,7 @@ namespace time { { boost::rational quot{cnt, _raw(timeReference)}; if (quot.denominator() < RATE_LIMIT - and quot.numerator() < RATE_LIMIT/1000) + and quot.numerator() < RATE_LIMIT*1024/1e6) return {uint(quot.numerator()) * uint(Time::SCALE) ,uint(quot.denominator()) }; diff --git a/src/vault/gear/activity-lang.hpp b/src/vault/gear/activity-lang.hpp index 65c251e45..42772d43c 100644 --- a/src/vault/gear/activity-lang.hpp +++ b/src/vault/gear/activity-lang.hpp @@ -122,6 +122,9 @@ namespace gear { /** @internal propagate new clean-up deadline to the BlockFlow allocator */ void discardBefore (Time deadline) { mem_.discardBefore (deadline); } + /** @internal announce expected additional load to the allocator */ + void announceLoad (FrameRate fps) { mem_.announceAdditionalFlow(fps); } + /** * Execution Framework: dispatch performance of a chain of Activities. diff --git a/src/vault/gear/block-flow.hpp b/src/vault/gear/block-flow.hpp index 5b9091716..f57e79641 100644 --- a/src/vault/gear/block-flow.hpp +++ b/src/vault/gear/block-flow.hpp @@ -389,15 +389,6 @@ namespace gear { epochStep_ = TimeValue{microTicks}; } - /** provide a hint to the self-regulating allocation scheme */ - void - announceAdditionalFlow (FrameRate additionalFps) - { - FrameRate currFps{config().framesPerEpoch(), epochStep_}; - /////////////////////////////////////////////////////////////////////TODO need arithmetics on FrameRate - /////////////////////////////////////////////////////////////////////TODO -> then just add the new and calculate new stepping - /////////////////////////////////////////////////////////////////////TODO !! watch out for the minimum limit !! - } /** Adapted storage-Extent iterator, directly exposing Epoch& */ @@ -596,6 +587,24 @@ namespace gear { } + /** + * provide a hint to the self-regulating allocation scheme. + * Signalling additional calculation flow in advance will + * immediately reduce the Epoch stepping to accommodate for + * more Activities per time unit, thereby preventing excessive + * overflow and reduced performance, until the mechanism has + * adapted itself to the actual situation after roughly 2sec. + */ + void + announceAdditionalFlow (FrameRate additionalFps) + { + FrameRate currFps{Strategy::framesPerEpoch(), Duration{epochStep_}}; + currFps += additionalFps; + TimeVar adaptedSpacing = Strategy::framesPerEpoch() / currFps; + epochStep_ = util::max (adaptedSpacing, _cache_timeStep_cutOff); + } + + private: Epoch& firstEpoch() diff --git a/src/vault/gear/scheduler.hpp b/src/vault/gear/scheduler.hpp index 36d102479..a0c03a343 100644 --- a/src/vault/gear/scheduler.hpp +++ b/src/vault/gear/scheduler.hpp @@ -303,9 +303,11 @@ namespace gear { */ void seedCalcStream (Job planningJob - ,ManifestationID manID = ManifestationID()) + ,ManifestationID manID = ManifestationID() + ,FrameRate expectedAdditionalLoad = FrameRate(25)) { - layer1_.activate(manID); + layer1_.activate (manID); + activityLang_.announceLoad (expectedAdditionalLoad); continueMetaJob (RealClock::now(), planningJob, manID); } diff --git a/tests/32scheduler.tests b/tests/32scheduler.tests index 34bb59d26..3619dab13 100644 --- a/tests/32scheduler.tests +++ b/tests/32scheduler.tests @@ -32,7 +32,7 @@ END -PLANNED "Scheduler Load-Control" SchedulerLoadControl_test < #include using test::Test; -using std::move; - -using std::chrono::microseconds; -//using util::isSameObject; namespace vault{ namespace gear { namespace test { -// using lib::time::FrameRate; -// using lib::time::Offset; -// using lib::time::Time; + using std::move; + using std::chrono::microseconds; + using Capacity = LoadController::Capacity; using Wiring = LoadController::Wiring; @@ -75,8 +66,6 @@ namespace test { classifyCapacity(); scatteredReCheck(); indicateAverageLoad(); - - walkingDeadline(); } @@ -99,7 +88,6 @@ namespace test { * Activities from the zone considered part of current active operation * - Activities within the NOW_HORIZON can be awaited by yield-spinning * - and any event from current into the past will be scheduled right away - * @todo WIP 10/23 ✔ define ⟶ ✔ implement */ void classifyHorizon() @@ -129,7 +117,6 @@ namespace test { /** @test verify the mark for _tended next head_ Activity. - * @todo WIP 10/23 ✔ define ⟶ ✔ implement */ void tendNextActivity() @@ -174,7 +161,6 @@ namespace test { * - beyond that, free capacity is redistributed according to horizon * - for incoming free capacity there is a preference to keep it sleeping, * to allow for disposing of excess capacity after extended sleep time - * @todo WIP 10/23 ✔ define ⟶ ✔ implement */ void classifyCapacity() @@ -253,7 +239,6 @@ namespace test { * the goal is to produce a random distribution of the »sleeper« callbacks. * - the offset is indeed randomised, using current time for randomisation * @see LoadController::scatteredDelayTime() - * @todo WIP 10/23 ✔ define ⟶ ✔ implement */ void scatteredReCheck() @@ -307,7 +292,6 @@ namespace test { * - the pressure is sampled from the lag (distance of current time to the * next activity to schedule), which is observed whenever a worker * calls in to retrieve more work. These calls happen randomly. - * @todo WIP 10/23 ✔ define ⟶ ✔ implement */ void indicateAverageLoad() @@ -373,17 +357,6 @@ namespace test { lctrl.markIncomingCapacity (head,curr); CHECK (-2581 == lctrl.averageLag()); } - - - - /** @test TODO - * @todo WIP 10/23 🔁 define ⟶ implement - */ - void - walkingDeadline() - { - UNIMPLEMENTED ("walking Deadline"); - } }; diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 83be0077a..c6087b3e9 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -82038,17 +82038,18 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + - - + + + - + @@ -82092,8 +82093,11 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - + + + + + @@ -82195,6 +82199,10 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + +
@@ -82401,8 +82409,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - + + @@ -82446,9 +82454,9 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - + + + @@ -93129,7 +93137,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -94209,9 +94217,9 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - + + + @@ -94223,14 +94231,74 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - + + - + + + + + + + +

+ wende wieder die gleiche Technik an, die ich für das ZoomWindow erfolgreich entwickelt hatte... +

+ +
+ + + + + + +
    +
  1. + feststellen, um wie viele Stellen die Zahl zu groß ist (binär-logarithmus) +
  2. +
  3. + den Nenner um diese Zahl nach rechts schieben ⟹ neuer quantisierer +
  4. +
  5. + mit diesem die Zahl re-quantisieren +
  6. +
  7. + daraus ein boost::rationall<uint> +
  8. +
+ + +
+
+ + +
+ + + + + + +
+ + + + +
    +
  • + aktuelle Framerate += zusätzliche Framerate +
  • +
  • + Framerate ⟹ neue Epochen-Dauer, setzen! +
  • +
+ +
+
@@ -95012,12 +95080,12 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - + + - + @@ -95031,12 +95099,13 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - - - - + + + + + + + @@ -95044,18 +95113,25 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - + + + + - + + - + + + + + @@ -96990,28 +97066,39 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - - - + + + + + + + + + + + - - + + + + + + + + + - - - - - - - - + + + + + + @@ -97093,7 +97180,10 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + + + +