Lumiera 0.pre.04~rc.1
»edit your freedom«
Loading...
Searching...
No Matches
sync-barrier-performance-test.cpp
Go to the documentation of this file.
1/*
2 SyncBarrierPerformance(Test) - investigate performance of yield-waiting synchronisation
3
4 Copyright (C)
5 2023, Hermann Vosseler <Ichthyostega@web.de>
6
7  **Lumiera** is free software; you can redistribute it and/or modify it
8  under the terms of the GNU General Public License as published by the
9  Free Software Foundation; either version 2 of the License, or (at your
10  option) any later version. See the file COPYING for further details.
11
12* *****************************************************************/
13
20#include "lib/test/run.hpp"
21#include "lib/sync-barrier.hpp"
23#include "lib/format-cout.hpp"
24#include "lib/sync.hpp"
25
26using test::Test;
27using std::array;
28
29
30namespace lib {
31namespace test {
32
33 namespace {// Test setup....
34
35 const uint NUM_STAGES = 1024;
36
42 {
43 public:
44 FakeBarrier(uint=0) { /* be happy */ }
45 void sync() { /* indulge */ }
46 };
47
48
54 : public Sync<NonrecursiveLock_Waitable>
55 {
56 int latch_;
57
58 bool allPassed() { return latch_ <= 0; }
59
60 public:
61 MonitorSync (uint nFold =2)
62 : latch_{int(nFold)}
63 { }
64
65 void
67 {
68 Lock sync{this};
69 --latch_;
70 sync.wait ([this]{ return allPassed(); });
71 sync.notify_all();
72 }
73
74 private:
75 };
76 }//(End)Test setup
77
78
79
80
81 /*******************************************************************/
92 {
93 template<class BAR, size_t nThreads>
94 double
96 {
97 BAR barrier[NUM_STAGES];
98 for (uint i=0; i<NUM_STAGES; ++i)
99 new(&barrier[i]) BAR{nThreads};
100
101 auto testSubject = [&](size_t i) -> size_t
102 {
103 barrier[i].sync();
104 return i; // prevent empty loop optimisation
105 };
106
107 auto [micros, cnt] = threadBenchmark<nThreads> (testSubject, NUM_STAGES);
108 CHECK (cnt == nThreads * NUM_STAGES*(NUM_STAGES-1)/2);
109 return micros;
110 }
111
112
113
136 virtual void
137 run (Arg)
138 {
139 cout<<"\n\n■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■□■"<<endl;
140
141 double time_yieldWait_80 = performanceTest<SyncBarrier, 80>();
142 double time_yieldWait_64 = performanceTest<SyncBarrier, 64>();
143 double time_yieldWait_48 = performanceTest<SyncBarrier, 48>();
144 double time_yieldWait_32 = performanceTest<SyncBarrier, 32>();
145 double time_yieldWait_16 = performanceTest<SyncBarrier, 16>();
146 double time_yieldWait_8 = performanceTest<SyncBarrier, 8>();
147 double time_yieldWait_4 = performanceTest<SyncBarrier, 4>();
148 double time_yieldWait_2 = performanceTest<SyncBarrier, 2>();
149 //
150 double time_emptySetup = performanceTest<FakeBarrier, 5>();
151 //
152 double time_sleepWait_16 = performanceTest<MonitorSync, 16>();
153 double time_sleepWait_8 = performanceTest<MonitorSync, 8>();
154 double time_sleepWait_4 = performanceTest<MonitorSync, 4>();
155 double time_sleepWait_2 = performanceTest<MonitorSync, 2>();
156
157 cout<<"\n___Microbenchmark_______ (µs)"
158 <<"\nemptySetup : "<<time_emptySetup
159 <<"\n : "
160 <<"\nSyncBarrier (2 Thr) : "<<time_yieldWait_2
161 <<"\nSyncBarrier (4 Thr) : "<<time_yieldWait_4
162 <<"\nSyncBarrier (8 Thr) : "<<time_yieldWait_8
163 <<"\nSyncBarrier (16 Thr) : "<<time_yieldWait_16
164 <<"\nSyncBarrier (32 Thr) : "<<time_yieldWait_32
165 <<"\nSyncBarrier (48 Thr) : "<<time_yieldWait_48
166 <<"\nSyncBarrier (64 Thr) : "<<time_yieldWait_64
167 <<"\nSyncBarrier (80 Thr) : "<<time_yieldWait_80
168 <<"\n : "
169 <<"\nMonitorWait (2 Thr) : "<<time_sleepWait_2
170 <<"\nMonitorWait (4 Thr) : "<<time_sleepWait_4
171 <<"\nMonitorWait (8 Thr) : "<<time_sleepWait_8
172 <<"\nMonitorWait (16 Thr) : "<<time_sleepWait_16
173 <<"\n________________________\n"
174 <<"\nbarriers..... "<<NUM_STAGES
175 <<endl;
176
177 // Unable to assert more than a sanity check here....
178 CHECK (time_emptySetup < time_yieldWait_4);
179 }
180 };
181
182
183
186
187
188
189}} // namespace lib::test
scoped guard to control the actual locking.
Definition sync.hpp:228
void wait(PRED &&predicate)
Definition sync.hpp:241
Facility for monitor object based locking.
Definition sync.hpp:210
A Monitor based reference implementation, using Mutex + Condition Variable for sleeping wait.
Abstract Base Class for all testcases.
Definition run.hpp:54
Automatically use custom string conversion in C++ stream output.
unsigned int uint
Definition integral.hpp:29
Functions to perform (multithreaded) timing measurement on a given functor.
Implementation namespace for support and library code.
Test runner and basic definitions for tests.
Simplistic test class runner.
#define LAUNCHER(_TEST_CLASS_, _GROUPS_)
Definition run.hpp:116
A N-fold synchronisation latch using yield-wait until fulfilment.
Object Monitor based synchronisation.