diff --git a/src/lib/incidence-count.hpp b/src/lib/incidence-count.hpp index 965bfa8f7..1cc1ba6df 100644 --- a/src/lib/incidence-count.hpp +++ b/src/lib/incidence-count.hpp @@ -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; - using Recording = std::vector; + using Sequence = vector; + using Recording = vector; 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 caseCntr{}; + vector thrdCntr{}; + vector caseTime{}; + vector thrdTime{}; + + template + static VAL + access (vector 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::max()+1; + vector active_case(numCases); + vector 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; } diff --git a/tests/library/incidence-count-test.cpp b/tests/library/incidence-count-test.cpp index a28a697bd..fc44d0a50 100644 --- a/tests/library/incidence-count-test.cpp +++ b/tests/library/incidence-count-test.cpp @@ -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 #include //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)))); } diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 75d63212a..292a4f38d 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -111064,26 +111064,47 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - + + - - + + - - + + + + + + + + + + + + + + + + + + + + + + + @@ -111092,8 +111113,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - + +