diff --git a/src/lib/incidence-count.hpp b/src/lib/incidence-count.hpp index bf1fded76..1ad7ed5ed 100644 --- a/src/lib/incidence-count.hpp +++ b/src/lib/incidence-count.hpp @@ -48,11 +48,9 @@ #define LIB_INCIDENCE_COUNT_H -//#include "lib/meta/function.hpp" #include "lib/nocopy.hpp" #include "lib/iter-explorer.hpp" -//#include #include #include #include @@ -63,7 +61,6 @@ namespace lib { -// using std::forward; using std::vector; /** @@ -211,7 +208,7 @@ namespace lib { /** - * Visit all data captured thus far, construct a unified timeline + * Visit all data captured thus far, construct an unified timeline * and then compute statistics evaluations to characterise observations. * @warning caller must ensure there was a barrier or visibility sync before invocation. */ diff --git a/src/lib/test/microbenchmark.hpp b/src/lib/test/microbenchmark.hpp index bb1403f84..c2c655698 100644 --- a/src/lib/test/microbenchmark.hpp +++ b/src/lib/test/microbenchmark.hpp @@ -146,10 +146,10 @@ namespace test{ * @remarks - the subject function will be _copied_ into each thread * - so `nThreads` copies of this function will run in parallel * - consider locking if this function accesses a shared closure. - * - if you pass a lambda, it is eligible for inlining followed - * by loop optimisation -- be sure to include some action, like - * e.g. accessing a volatile variable, to prevent the compiler - * from entirely optimising it away altogether. + * - if you pass a lambda, it is eligible for inlining followed by + * loop optimisation -- be sure to include an observable effect, + * like returning a value tied to the actual computation, to + * prevent the compiler from optimising it away altogether. */ template inline auto diff --git a/tests/15library.tests b/tests/15library.tests index ecc06158f..233161a60 100644 --- a/tests/15library.tests +++ b/tests/15library.tests @@ -424,7 +424,7 @@ return: 0 END -PLANNED "Instrumentation: concurrent calls" IncidenceCount_test < #include -//using std::string; using util::isLimited; using std::this_thread::sleep_for; using std::chrono_literals::operator ""ms; @@ -57,9 +55,11 @@ namespace test{ - /***************************************************************************//** - * @test verifies capturing and restoring of std::ostream formatting state. - * @see ios-savepoint.hpp + /***************************************************************//** + * @test verify recording and evaluation of concurrent invocations + * of a piece of code instrumented for investigation. + * @see incidence-count.hpp + * @see vault::gear::TestChainLoad::ScheduleCtx */ class IncidenceCount_test : public Test @@ -168,7 +168,7 @@ SHOW_EXPR(stat.timeThread(1)); } - /** @test TODO verify observation of concurrency degree + /** @test verify observation of concurrency degree * @todo WIP 2/24 โœ” define โŸถ โœ” implement */ void @@ -260,17 +260,18 @@ SHOW_EXPR(stat.timeAtConc(3)); /** @test TODO verify thread-safe operation under pressure - * @todo WIP 2/24 ๐Ÿ” define โŸถ implement + * @todo WIP 2/24 โœ” define โŸถ โœ” implement */ void perform_multithreadStressTest() { MARK_TEST_FUN - const size_t CONCURR = std::thread::hardware_concurrency(); + constexpr size_t CONCURR = 16; + const size_t REPETITIONS = 100; IncidenceCount watch; watch.expectThreads(CONCURR) - .expectIncidents(5000); + .expectIncidents(10000); auto act = [&]{ // two nested activities with random delay uint delay = 100 + rand() % 800; @@ -282,6 +283,77 @@ SHOW_EXPR(stat.timeAtConc(3)); watch.markLeave(); }; + auto [runTime, sum] = test::threadBenchmark (act, REPETITIONS); +SHOW_EXPR(runTime) +SHOW_EXPR(sum) + CHECK (1600 == sum); + CHECK (isLimited (900, runTime, 1400)); // delay is 500ยตs on average + + auto stat = watch.evaluate(); +SHOW_EXPR(stat.cumulatedTime); +SHOW_EXPR(stat.activeTime); +SHOW_EXPR(stat.coveredTime); + CHECK (isLimited (900*REPETITIONS, stat.coveredTime, 1400*REPETITIONS)); + CHECK (stat.activeTime > 900 * REPETITIONS * CONCURR); +SHOW_EXPR(stat.eventCnt); +SHOW_EXPR(stat.activationCnt); + CHECK (stat.activationCnt == 2*REPETITIONS*CONCURR); +SHOW_EXPR(stat.cntCase(0)); + CHECK (stat.cntCase(0) == REPETITIONS*CONCURR); +SHOW_EXPR(stat.cntCase(1)); + CHECK (stat.cntCase(1) == 0); +SHOW_EXPR(stat.cntCase(2)); + CHECK (stat.cntCase(2) == REPETITIONS*CONCURR); +SHOW_EXPR(stat.cntCase(3)); +SHOW_EXPR(stat.timeCase(0)); +SHOW_EXPR(stat.timeCase(1)); +SHOW_EXPR(stat.timeCase(2)); +SHOW_EXPR(stat.timeCase(3)); +SHOW_EXPR(stat.cntThread(0)); +SHOW_EXPR(stat.cntThread(1)); +SHOW_EXPR(stat.cntThread(2)); +SHOW_EXPR(stat.cntThread(3)); +SHOW_EXPR(stat.cntThread(4)); +SHOW_EXPR(stat.cntThread(5)); +SHOW_EXPR(stat.cntThread(6)); +SHOW_EXPR(stat.cntThread(7)); +SHOW_EXPR(stat.cntThread(8)); +SHOW_EXPR(stat.cntThread(9)); +SHOW_EXPR(stat.timeThread(0)); +SHOW_EXPR(stat.timeThread(1)); +SHOW_EXPR(stat.timeThread(2)); +SHOW_EXPR(stat.timeThread(3)); +SHOW_EXPR(stat.timeThread(4)); +SHOW_EXPR(stat.timeThread(5)); +SHOW_EXPR(stat.timeThread(6)); +SHOW_EXPR(stat.timeThread(7)); +SHOW_EXPR(stat.timeThread(8)); +SHOW_EXPR(stat.timeThread(9)); +SHOW_EXPR(stat.avgConcurrency); + CHECK (isLimited(CONCURR/2, stat.avgConcurrency, CONCURR)); + for (uint i=0; i - + @@ -111012,8 +111012,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - + + @@ -111099,8 +111099,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - + + @@ -111110,8 +111110,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - + +