diff --git a/src/lib/incidence-count.hpp b/src/lib/incidence-count.hpp index 2529c03b9..965bfa8f7 100644 --- a/src/lib/incidence-count.hpp +++ b/src/lib/incidence-count.hpp @@ -50,6 +50,7 @@ //#include "lib/meta/function.hpp" #include "lib/nocopy.hpp" +#include "lib/iter-explorer.hpp" //#include #include @@ -57,6 +58,7 @@ #include #include #include +#include namespace lib { @@ -82,7 +84,7 @@ namespace lib { struct Inc { - Instance when{}; + Instance when; uint8_t thread :8; uint8_t caseID :8; bool isLeave :1; @@ -110,17 +112,28 @@ namespace lib { return threadID; } - Sequence - getMySequence() + Sequence& + getMySequence(uint8_t threadID) { - uint8_t id{getMySlot()}; - if (id >= rec_.size()) + if (threadID >= rec_.size()) { - rec_.reserve (id); - for (size_t i = rec_.size(); i < id; ++i) + rec_.reserve (threadID+1); + for (size_t i = rec_.size(); i < threadID+1u; ++i) rec_.emplace_back(); } - return rec_[id]; + return rec_[threadID]; + } + + void + addEntry(uint8_t caseID, bool isLeave) + { + uint8_t threadID{getMySlot()}; + Sequence& seq = getMySequence(threadID); + Inc& incidence = seq.emplace_back(); + incidence.when = Clock::now(); + incidence.thread = threadID; + incidence.caseID = caseID; + incidence.isLeave = isLeave; } @@ -151,28 +164,74 @@ namespace lib { /* ===== Measurement API ===== */ - void - markEnter(uint8_t caseID =0) - { - UNIMPLEMENTED ("Incidence measurement"); - } - - void - markLeave(uint8_t caseID =0) - { - UNIMPLEMENTED ("Incidence measurement"); - } + void markEnter(uint8_t caseID =0) { addEntry(caseID, false); } + void markLeave(uint8_t caseID =0) { addEntry(caseID, true); } /* ===== Evaluations ===== */ + struct Statistic + { + double cumulatedTime{0}; + }; + + Statistic evaluate(); + double calcCumulatedTime() { - UNIMPLEMENTED ("Evaluation"); + return evaluate().cumulatedTime; } + }; + + /** + * Visit all data captured thus far, construct a unified timeline + * and then compute statistics evaluations to characterise observations + * @warning caller must ensure there was a barrier or visibility sync before invocation. + */ + IncidenceCount::Statistic + IncidenceCount::evaluate() + { + Statistic stat; + size_t numThreads = rec_.size(); + if (numThreads == 0) return stat; + + size_t numEvents = explore(rec_) + .transform([](Sequence& seq){ return seq.size(); }) + .resultSum(); + if (numEvents == 0) return stat; + Sequence timeline; + timeline.reserve(numEvents); + for (Sequence& seq : rec_) + for (Inc& event : seq) + timeline.emplace_back(event); + std::sort (timeline.begin(), timeline.end() + ,[](Inc const& l, Inc const& r) { return l.when < r.when; } + ); + + int active{0}; + Instance prev = timeline.front().when; + for (Inc& event : timeline) + { + if (event.isLeave) + { + ASSERT (0 < active); + Dur timeSlice = event.when - prev; + stat.cumulatedTime += active * timeSlice.count(); + --active; + } + else + { + ++active; + } + prev = event.when; + } + return stat; + } + + } // namespace lib #endif /*LIB_INCIDENCE_COUNT_H*/ diff --git a/tests/library/incidence-count-test.cpp b/tests/library/incidence-count-test.cpp index 2860b96de..a28a697bd 100644 --- a/tests/library/incidence-count-test.cpp +++ b/tests/library/incidence-count-test.cpp @@ -61,8 +61,8 @@ namespace test{ - /** @test TODO - * @todo WIP 2/24 🔁 define ⟶ implement + /** @test watch time spent in code bracketed by measurement calls. + * @todo WIP 2/24 ✔ define ⟶ ✔ implement */ void demonstrate_usage() @@ -71,11 +71,17 @@ namespace test{ watch.markEnter(); sleep_for (1ms); watch.markLeave(); + // + sleep_for (5ms); + // + watch.markEnter(); + sleep_for (1ms); + watch.markLeave(); double time = watch.calcCumulatedTime(); SHOW_EXPR(time) - CHECK (time > 900); - CHECK (time < 1100); + CHECK (time > 1900); + CHECK (time < 2500); } diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index ac0c969cd..75d63212a 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -111033,8 +111033,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - + + @@ -111053,32 +111053,44 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - - + + + + - - + + - - - - + + + + - - + + + + + + + + + + + + + + + + - - - - + +