Scheduler-test: binary search over continuous domain
- textbook implementation - capture results from visited points - average results form the last three points to damp statistic fluctuations
This commit is contained in:
parent
54e489b9b6
commit
bf1eac02dd
2 changed files with 148 additions and 8 deletions
|
|
@ -81,6 +81,7 @@
|
|||
#include "vault/gear/scheduler.hpp"
|
||||
#include "lib/time/timevalue.hpp"
|
||||
//#include "lib/iter-explorer.hpp"
|
||||
#include "lib/meta/function.hpp"
|
||||
#include "lib/format-string.hpp"
|
||||
#include "lib/format-cout.hpp"//////////////////////////TODO RLY?
|
||||
//#include "lib/util.hpp"
|
||||
|
|
@ -99,8 +100,8 @@ namespace gear {
|
|||
namespace test {
|
||||
|
||||
using util::_Fmt;
|
||||
// using util::min;
|
||||
// using util::max;
|
||||
using util::min;
|
||||
using util::max;
|
||||
// using util::isnil;
|
||||
// using util::limited;
|
||||
// using util::unConst;
|
||||
|
|
@ -115,7 +116,7 @@ namespace test {
|
|||
|
||||
// using std::string;
|
||||
// using std::function;
|
||||
// using std::make_pair;
|
||||
using std::make_pair;
|
||||
using std::make_tuple;
|
||||
// using std::forward;
|
||||
// using std::string;
|
||||
|
|
@ -130,6 +131,71 @@ namespace test {
|
|||
|
||||
namespace stress_test_rig {
|
||||
|
||||
template<class X, class P>
|
||||
struct _ValidateBinarySearchFun
|
||||
{
|
||||
static_assert (not sizeof(P), "Functor unsuitable for binary search. "
|
||||
"Expected signature pair<bool,X>(PAR)" );
|
||||
};
|
||||
template<class RES, class PAR>
|
||||
struct _ValidateBinarySearchFun<std::pair<bool,RES>(PAR), PAR>
|
||||
{
|
||||
using Result = RES;
|
||||
};
|
||||
template<class FUN, typename PAR>
|
||||
inline auto
|
||||
make_binarySearchResults()
|
||||
{
|
||||
using Sig = typename lib::meta::_Fun<FUN>::Sig;
|
||||
using Res = typename _ValidateBinarySearchFun<Sig,PAR>::Result;
|
||||
using Data = std::vector<std::pair<bool, Res>>;
|
||||
return Data{};
|
||||
}
|
||||
|
||||
template<class FUN, class CON, typename PAR>
|
||||
inline auto
|
||||
binarySearch_impl (FUN&& fun, CON results, PAR lower, PAR upper, PAR epsilon)
|
||||
{
|
||||
REQUIRE (lower <= upper);
|
||||
while ((upper-lower) >= epsilon)
|
||||
{
|
||||
PAR div = (upper-lower) / 2;
|
||||
results.emplace_back (fun(div));
|
||||
bool hit = results.back().first;
|
||||
if (hit)
|
||||
upper = div;
|
||||
else
|
||||
lower = div;
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
template<class FUN, typename PAR>
|
||||
inline auto
|
||||
binarySearch_inner (FUN&& fun, PAR lower, PAR upper, PAR epsilon)
|
||||
{
|
||||
auto results = make_binarySearchResults<FUN,PAR>();
|
||||
return binarySearch_impl(forward<FUN> (fun), results, lower,upper,epsilon);
|
||||
}
|
||||
|
||||
template<class FUN, typename PAR>
|
||||
inline auto
|
||||
binarySearch_upper (FUN&& fun, PAR lower, PAR upper, PAR epsilon)
|
||||
{
|
||||
REQUIRE (lower <= upper);
|
||||
auto results = make_binarySearchResults<FUN,PAR>();
|
||||
results.emplace_back (fun(upper));
|
||||
bool hit = results.back().first;
|
||||
if (not hit)
|
||||
{// the upper end breaks contract => search above
|
||||
PAR len = (upper-lower);
|
||||
lower = upper - len/10;
|
||||
upper = lower + 14*len/10;
|
||||
}
|
||||
return binarySearch_impl(forward<FUN> (fun), results, lower,upper,epsilon);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Specific stress test scheme to determine the
|
||||
* »breaking point« where the Scheduler starts to slip
|
||||
|
|
@ -207,7 +273,30 @@ namespace test {
|
|||
Res
|
||||
conductBinarySearch (FUN&& runTestCase)
|
||||
{
|
||||
UNIMPLEMENTED ("invoke a library implementation of binary search");
|
||||
auto results = binarySearch_upper (forward<FUN> (runTestCase), 0.0, CONF::UPPER_STRESS, CONF::EPSILON);
|
||||
uint s = results.size();
|
||||
ENSURE (s >= 2);
|
||||
Res res;
|
||||
auto& [sf,pf,sdev,avgD,avgT,expT] = res;
|
||||
// average data over the last three steps investigated for smoothing
|
||||
uint points = min (results.size(), 3u);
|
||||
for (uint i=results.size()-points; i<results.size(); ++i)
|
||||
{
|
||||
Res resx = results[i].second;
|
||||
pf += resx.percentOff;
|
||||
sdev += resx.stdDev;
|
||||
avgD += resx.avgDelta;
|
||||
avgT += resx.avgTime;
|
||||
expT += resx.expTime;
|
||||
}
|
||||
pf /= points;
|
||||
sdev /= points;
|
||||
avgD /= points;
|
||||
avgT /= points;
|
||||
expT /= points;
|
||||
// »breaking point« stress in the middle of the last interval
|
||||
sf = (results[s-1].second.stressFac + results[s-2].second.stressFac) / 2;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -273,7 +362,7 @@ namespace test {
|
|||
{
|
||||
configureTest (testSetup, stressFac);
|
||||
auto res = runProbes (testSetup, stressFac);
|
||||
return make_tuple (decideBreakPoint(res), res);
|
||||
return make_pair (decideBreakPoint(res), res);
|
||||
};
|
||||
|
||||
Res res = conductBinarySearch (move (performEvaluation));
|
||||
|
|
@ -294,7 +383,9 @@ namespace test {
|
|||
|
||||
usec LOAD_BASE = 500us;
|
||||
uint CONCURRENCY = work::Config::getDefaultComputationCapacity();
|
||||
double FAIL_LIMIT = 2.0; ///< delta-limit when to count a run as failure
|
||||
double EPSILON = 0.01; ///< error bound to abort binary search
|
||||
double UPPER_STRESS = 0.6; ///< starting point for the upper limit, likely to fail
|
||||
double FAIL_LIMIT = 2.0; ///< delta-limit when to count a run as failure
|
||||
double TRIGGER_FAIL = 0.55; ///< %-fact: criterion-1 failures above this rate
|
||||
double TRIGGER_SDEV = FAIL_LIMIT; ///< in ms : criterion-2 standard derivation
|
||||
double TRIGGER_DELTA = 2*FAIL_LIMIT; ///< in ms : criterion-3 delta above this limit
|
||||
|
|
|
|||
|
|
@ -107830,11 +107830,60 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node CREATED="1704237555914" ID="ID_1779084715" MODIFIED="1704237568213" TEXT="funktionale Konfigurations-Hooks"/>
|
||||
<node CREATED="1704237569280" ID="ID_227955379" MODIFIED="1704237574469" TEXT="Basis-Setup einmischen"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1704243593362" ID="ID_1513298833" MODIFIED="1704243606440" TEXT="Statistik-Berechnung integrieren">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1704243593362" ID="ID_1513298833" MODIFIED="1704316330671" TEXT="Statistik-Berechnung integrieren">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1704243607600" ID="ID_1968188887" MODIFIED="1704243618662" TEXT="Lib-Implementierung: binäre Suche">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#338800" CREATED="1704316333600" ID="ID_198671243" MODIFIED="1704322903614" TEXT="Basis-Algo">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1704316348241" ID="ID_118215771" MODIFIED="1704316368237" TEXT="Parameter-Range [lower, upper]"/>
|
||||
<node CREATED="1704316374393" ID="ID_1441038472" MODIFIED="1704317029516" TEXT="Invariante: test(lower) ≡ false ∧ test(upper) ≡ true">
|
||||
<node BACKGROUND_COLOR="#ccb59b" COLOR="#6e2a38" CREATED="1704316425945" ID="ID_242995900" MODIFIED="1704317035203" TEXT="das wird Eingangs nicht geprüft">
|
||||
<font ITALIC="true" NAME="SansSerif" SIZE="14"/>
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node CREATED="1704317043838" ID="ID_1366116745" MODIFIED="1704317054641" TEXT="dann stellt es jede Iteration wieder her"/>
|
||||
</node>
|
||||
<node CREATED="1704316569022" ID="ID_1489985848" MODIFIED="1704316590391" TEXT="Vorgabe Such-Genauigkeit ε">
|
||||
<node CREATED="1704316840481" ID="ID_1649502723" MODIFIED="1704316856915" TEXT="solange Intervall größer, wird geteilt"/>
|
||||
<node CREATED="1704316870382" ID="ID_546344675" MODIFIED="1704316917969" TEXT="sonst wird die Intervallmitte zum Ergebnis"/>
|
||||
<node CREATED="1704316928158" ID="ID_208081940" MODIFIED="1704316942065" TEXT="⟹ Fehler < ε"/>
|
||||
</node>
|
||||
<node CREATED="1704317059760" ID="ID_1022278502" MODIFIED="1704317061951" TEXT="Iteration">
|
||||
<node CREATED="1704317071234" ID="ID_731227047" MODIFIED="1704317076070" TEXT="Abbruch prüfen"/>
|
||||
<node CREATED="1704317076874" ID="ID_699422154" MODIFIED="1704317104362" TEXT="Intervall teilen: m"/>
|
||||
<node CREATED="1704317083038" ID="ID_1260760369" MODIFIED="1704317115617">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Mittelpunkt <b>auswerten</b>: test(m)
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<node CREATED="1704317129562" ID="ID_160740709" MODIFIED="1704317166218" TEXT="true ⟼ [lower, m]"/>
|
||||
<node CREATED="1704317167008" ID="ID_227786504" MODIFIED="1704317178064" TEXT="false ⟼ [m, upper]"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1704317215639" ID="ID_250813072" MODIFIED="1704317220333" TEXT="Einstiegs-Varianten">
|
||||
<node CREATED="1704317372561" ID="ID_902270424" MODIFIED="1704317376906" TEXT="lower prüfen">
|
||||
<node CREATED="1704317242076" ID="ID_540462019" MODIFIED="1704317358168" TEXT="true ⟼ Intervallverschiebung+Vergrößerung ▽"/>
|
||||
<node CREATED="1704317389152" ID="ID_1595570689" MODIFIED="1704317398327" TEXT="sonst: upper prüfen"/>
|
||||
</node>
|
||||
<node CREATED="1704317230133" ID="ID_821454359" MODIFIED="1704317232648" TEXT="upper prüfen">
|
||||
<node CREATED="1704317242076" ID="ID_1523564757" MODIFIED="1704317363990" TEXT="false ⟼ Intervallverschiebung+Vergrößerung △"/>
|
||||
<node CREATED="1704317412253" ID="ID_884069153" MODIFIED="1704317421832" TEXT="sonst Basis-Algo [lower, upper]"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1704317427155" ID="ID_366800456" MODIFIED="1704317431566" TEXT="Datensammlung">
|
||||
<node CREATED="1704317465350" ID="ID_1437456177" MODIFIED="1704317479448" TEXT="Ergebnistupel aller Auswertungen werden in einem Vector gesammelt"/>
|
||||
<node CREATED="1704317540235" ID="ID_696343908" MODIFIED="1704317608812" TEXT="man kann dann das letzte Ergebnis nehmen, oder mehrere mitteln"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue