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:
parent
08847ae283
commit
a1abed68f4
3 changed files with 148 additions and 19 deletions
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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))));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -111064,26 +111064,47 @@ Date:   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ähl-Durchgang">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1707754935094" ID="ID_252947705" MODIFIED="1707787301134" TEXT="Zä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ählen">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1707770439946" ID="ID_905201900" MODIFIED="1707770474857" TEXT="muß dann ggfs Array von Zählern anlegen">
|
||||
<icon BUILTIN="hourglass"/>
|
||||
<node COLOR="#338800" CREATED="1707770439946" ID="ID_905201900" MODIFIED="1707787229437" TEXT="muß dann Vector von Zä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änkt ⟹ stupide ein Slot für jede mö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 ü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ählen">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -111092,8 +111113,8 @@ Date:   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"/>
|
||||
|
|
|
|||
Loading…
Reference in a new issue