Scheduler-test: implement differentiated statistics counting for instrumentation

...break down the integration of the activation count over time
   into individual accounting
   - for each caseID
   - for each thread
This commit is contained in:
Fischlurch 2024-02-13 02:25:52 +01:00
parent 08847ae283
commit a1abed68f4
3 changed files with 148 additions and 19 deletions

View file

@ -64,6 +64,7 @@
namespace lib {
// using std::forward;
using std::vector;
/**
* A recorder for concurrent incidences.
@ -90,8 +91,8 @@ namespace lib {
bool isLeave :1;
};
using Sequence = std::vector<Inc>;
using Recording = std::vector<Sequence>;
using Sequence = vector<Inc>;
using Recording = vector<Sequence>;
Recording rec_;
@ -145,9 +146,7 @@ namespace lib {
expectThreads(uint8_t cnt)
{
REQUIRE (cnt);
rec_.reserve (cnt);
for ( ; cnt; --cnt)
rec_.emplace_back();
rec_.resize (cnt);
return *this;
}
@ -172,7 +171,27 @@ namespace lib {
struct Statistic
{
size_t eventCnt{0};
size_t activationCnt{0};
double cumulatedTime{0};
double coveredTime{0};
vector<size_t> caseCntr{};
vector<size_t> thrdCntr{};
vector<double> caseTime{};
vector<double> thrdTime{};
template<typename VAL>
static VAL
access (vector<VAL> const& data, size_t idx)
{
return idx < data.size()? data[idx]
: VAL{};
}
size_t cntCase (size_t id) { return access (caseCntr, id); }
size_t cntThread(size_t id) { return access (thrdCntr, id); }
double timeCase (size_t id) { return access (caseTime, id); }
double timeThread(size_t id) { return access (thrdTime, id); }
};
Statistic evaluate();
@ -189,7 +208,7 @@ namespace lib {
/**
* Visit all data captured thus far, construct a unified timeline
* and then compute statistics evaluations to characterise observations
* and then compute statistics evaluations to characterise observations.
* @warning caller must ensure there was a barrier or visibility sync before invocation.
*/
IncidenceCount::Statistic
@ -213,22 +232,52 @@ namespace lib {
);
int active{0};
size_t numCases = std::numeric_limits<uint8_t>::max()+1;
vector<int> active_case(numCases);
vector<int> active_thrd(numThreads);
stat.thrdCntr.resize (numThreads);
stat.thrdTime.resize (numThreads);
// Integrate over the timeline...
// - book the preceding interval length into each affected partial sum
// - adjust current active count in accordance to the current event
Instance prev = timeline.front().when;
for (Inc& event : timeline)
{
if (event.caseID >= stat.caseCntr.size())
{
stat.caseCntr.resize (event.caseID+1);
stat.caseTime.resize (event.caseID+1);
}
Dur timeSlice = event.when - prev;
stat.cumulatedTime += active * timeSlice.count();
for (uint i=0; i < stat.caseCntr.size(); ++i)
stat.caseTime[i] += active_case[i] * timeSlice.count();
for (uint i=0; i < numThreads; ++i)
stat.thrdTime[i] += active_thrd[i] * timeSlice.count();
if (event.isLeave)
{
ASSERT (0 < active);
Dur timeSlice = event.when - prev;
stat.cumulatedTime += active * timeSlice.count();
ASSERT (0 < active_case[event.caseID]);
ASSERT (0 < active_thrd[event.thread]);
--active;
--active_case[event.caseID];
--active_thrd[event.thread];
}
else
{
++active;
++active_case[event.caseID];
++active_thrd[event.thread];
++stat.caseCntr[event.caseID];
++stat.thrdCntr[event.thread];
++stat.activationCnt;
}
prev = event.when;
}
Dur covered = timeline.back().when - timeline.front().when;
stat.coveredTime = covered.count();
stat.eventCnt = timeline.size();
return stat;
}

View file

@ -28,12 +28,14 @@
#include "lib/test/run.hpp"
#include "lib/test/diagnostic-output.hpp"//////////////TODO RLY?
#include "lib/incidence-count.hpp"
#include "lib/util.hpp"
//#include <string>
#include <thread>
//using std::string;
using util::isLimited;
using std::this_thread::sleep_for;
using std::chrono_literals::operator ""ms;
@ -79,19 +81,76 @@ namespace test{
watch.markLeave();
double time = watch.calcCumulatedTime();
SHOW_EXPR(time)
CHECK (time > 1900);
CHECK (time < 2500);
}
/** @test TODO verify proper counting of possibly overlapping incidences
* @todo WIP 2/24 🔁 define implement
* @todo WIP 2/24 define 🔁 implement
*/
void
verify_incidentCount()
{
UNIMPLEMENTED("verify proper counting of possibly overlapping incidences");
IncidenceCount watch;
watch.expectThreads(1)
.expectIncidents(20);
watch.markEnter(1);
sleep_for (1ms);
watch.markEnter(3);
sleep_for (2ms);
watch.markEnter(2);
watch.markLeave(3);
sleep_for (1ms);
watch.markLeave(1);
watch.markEnter(3);
sleep_for (3ms);
watch.markEnter(1);
watch.markLeave(2);
sleep_for (1ms);
watch.markLeave(3);
sleep_for (1ms);
watch.markLeave(1);
auto stat = watch.evaluate();
SHOW_EXPR(stat.cumulatedTime);
SHOW_EXPR(stat.coveredTime);
SHOW_EXPR(stat.eventCnt);
SHOW_EXPR(stat.activationCnt);
SHOW_EXPR(stat.cntCase(0));
SHOW_EXPR(stat.cntCase(1));
SHOW_EXPR(stat.cntCase(2));
SHOW_EXPR(stat.cntCase(3));
SHOW_EXPR(stat.cntCase(4));
SHOW_EXPR(stat.timeCase(0));
SHOW_EXPR(stat.timeCase(1));
SHOW_EXPR(stat.timeCase(2));
SHOW_EXPR(stat.timeCase(3));
SHOW_EXPR(stat.timeCase(4));
SHOW_EXPR(stat.cntThread(0));
SHOW_EXPR(stat.cntThread(1));
SHOW_EXPR(stat.timeThread(0));
SHOW_EXPR(stat.timeThread(1));
CHECK (isLimited (15500, stat.cumulatedTime, 17500)); // ≈ 16ms
CHECK (isLimited ( 8500, stat.coveredTime, 10000)); // ≈ 9ms
CHECK (10== stat.eventCnt);
CHECK (5 == stat.activationCnt);
CHECK (0 == stat.cntCase(0));
CHECK (2 == stat.cntCase(1));
CHECK (1 == stat.cntCase(2));
CHECK (2 == stat.cntCase(3));
CHECK (0 == stat.cntCase(4));
CHECK (0 == stat.timeCase(0));
CHECK (isLimited ( 5500, stat.timeCase(1), 6800)); // ≈ 6ms
CHECK (isLimited ( 3500, stat.timeCase(2), 4500)); // ≈ 4ms
CHECK (isLimited ( 5500, stat.timeCase(3), 6800)); // ≈ 6ms
CHECK (0 == stat.timeCase(4));
CHECK (5 == stat.cntThread(0));
CHECK (0 == stat.cntThread(1));
CHECK (stat.cumulatedTime == stat.timeThread(0));
CHECK (0 == stat.timeThread(1));
CHECK (1 > abs(stat.cumulatedTime - (stat.timeCase(1) + stat.timeCase(2) + stat.timeCase(3))));
}

View file

@ -111064,26 +111064,47 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1707754873263" ID="ID_961298794" MODIFIED="1707768327245" TEXT="Statistik-Auswertung">
<icon BUILTIN="pencil"/>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1707754895979" ID="ID_1713684347" MODIFIED="1707768321390" TEXT="Statistik-Record">
<icon BUILTIN="pencil"/>
<node COLOR="#338800" CREATED="1707754895979" ID="ID_1713684347" MODIFIED="1707787270143" TEXT="Statistik-Record">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1707754913201" ID="ID_177410967" MODIFIED="1707768324431" TEXT="Incident-Timeline etablieren">
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1707754935094" ID="ID_252947705" MODIFIED="1707768333278" TEXT="Z&#xe4;hl-Durchgang">
<icon BUILTIN="pencil"/>
<node COLOR="#338800" CREATED="1707754935094" ID="ID_252947705" MODIFIED="1707787301134" TEXT="Z&#xe4;hl-Durchgang">
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1707770397112" ID="ID_38773008" MODIFIED="1707770410383" TEXT="Berechnungs-Metode">
<icon BUILTIN="button_ok"/>
<node COLOR="#435e98" CREATED="1707770411960" ID="ID_1355812150" MODIFIED="1707770438948" TEXT="Zeit-Intervalle Slot-weise z&#xe4;hlen">
<icon BUILTIN="idea"/>
</node>
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1707770439946" ID="ID_905201900" MODIFIED="1707770474857" TEXT="mu&#xdf; dann ggfs Array von Z&#xe4;hlern anlegen">
<icon BUILTIN="hourglass"/>
<node COLOR="#338800" CREATED="1707770439946" ID="ID_905201900" MODIFIED="1707787229437" TEXT="mu&#xdf; dann Vector von Z&#xe4;hlern anlegen">
<icon BUILTIN="button_ok"/>
</node>
</node>
<node COLOR="#338800" CREATED="1707770479301" ID="ID_1026958053" MODIFIED="1707770500545" TEXT="einfachste Auswertung: beobachtete Zeit in aktiven Intervallen">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1707787232318" ID="ID_395659855" MODIFIED="1707787262617" TEXT="die gleiche Logik herunterbrechen...">
<icon BUILTIN="button_ok"/>
<node COLOR="#338800" CREATED="1707787241556" ID="ID_935542659" MODIFIED="1707787262618" TEXT="auf ein Accounting pro caseID">
<icon BUILTIN="button_ok"/>
</node>
<node COLOR="#338800" CREATED="1707787250987" ID="ID_253025585" MODIFIED="1707787262617" TEXT="auf ein Accounting pro Thread">
<icon BUILTIN="button_ok"/>
</node>
</node>
<node COLOR="#435e98" CREATED="1707787356980" ID="ID_1654307998" MODIFIED="1707787393442" TEXT="caseID ist per Datentyp beschr&#xe4;nkt &#x27f9; stupide ein Slot f&#xfc;r jede m&#xf6;gliche ID">
<icon BUILTIN="idea"/>
</node>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1707787292247" ID="ID_1168581526" MODIFIED="1707787298581" TEXT="Concurrency buchen">
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1707787306154" ID="ID_545614192" MODIFIED="1707787347330" TEXT="globales gewichtetes Mittel &#xfc;ber alle Segmente">
<icon BUILTIN="flag-yellow"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1707787318991" ID="ID_1203625704" MODIFIED="1707787347331" TEXT="Zeiten auf bestimmtem Concurrency-Niveau separat z&#xe4;hlen">
<icon BUILTIN="flag-yellow"/>
</node>
</node>
</node>
</node>
@ -111092,8 +111113,8 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node COLOR="#338800" CREATED="1707754993819" ID="ID_1476552932" MODIFIED="1707770394988" TEXT="demonstrate_simpleUsage">
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1707755010724" ID="ID_6728381" MODIFIED="1707755044792" TEXT="verify_incidentCount">
<icon BUILTIN="flag-yellow"/>
<node COLOR="#338800" CREATED="1707755010724" ID="ID_6728381" MODIFIED="1707787282628" TEXT="verify_incidentCount">
<icon BUILTIN="button_ok"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1707755017591" ID="ID_464212476" MODIFIED="1707755044792" TEXT="verify_multithreadCount">
<icon BUILTIN="flag-yellow"/>