diff options
author | Haley Connelly <haley.connelly@mongodb.com> | 2022-11-11 14:48:48 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-11-11 15:40:41 +0000 |
commit | 48dce7079ead4ec78311132a2e2224b2512ef0d3 (patch) | |
tree | 2faaf08c15ce0739c5f4aaec472b193f81913e9c | |
parent | 977cf573cb8e924390e6f9108a1f9d28caf02199 (diff) | |
download | mongo-48dce7079ead4ec78311132a2e2224b2512ef0d3.tar.gz |
SERVER-71119 Add PriorityTicketHolder benchmark comparable to SemaphoreTicketHolder
-rw-r--r-- | src/mongo/util/concurrency/ticketholder_bm.cpp | 73 |
1 files changed, 57 insertions, 16 deletions
diff --git a/src/mongo/util/concurrency/ticketholder_bm.cpp b/src/mongo/util/concurrency/ticketholder_bm.cpp index 19b75c18bc3..a3ee1a14768 100644 --- a/src/mongo/util/concurrency/ticketholder_bm.cpp +++ b/src/mongo/util/concurrency/ticketholder_bm.cpp @@ -47,6 +47,17 @@ static int kThreadMax = 1024; static int kLowPriorityAdmissionBypassThreshold = 100; static TicketHolder::WaitMode waitMode = TicketHolder::WaitMode::kUninterruptible; +// For a given benchmark, specifies the AdmissionContext::Priority of ticket admissions +enum class AdmissionsPriority { + // All admissions must be AdmissionContext::Priority::kNormal. + kNormal, + // Admissions may vary between AdmissionContext::Priority::kNormal and + // AdmissionContext::Priority::kLow. + kNormalAndLow, + // All admissions must be AdmissionContext::Priority::kLow. + kLow, +}; + template <typename TicketHolderImpl> class TicketHolderFixture { public: @@ -76,10 +87,9 @@ static Mutex isReadyMutex; static stdx::condition_variable isReadyCv; static bool isReady = false; -template <class TicketHolderImpl> +template <class TicketHolderImpl, AdmissionsPriority admissionsPriority> void BM_acquireAndRelease(benchmark::State& state) { - static std::unique_ptr<TicketHolderFixture<TicketHolderImpl>> readTicketHolder; - static std::unique_ptr<TicketHolderFixture<TicketHolderImpl>> writeTicketHolder; + static std::unique_ptr<TicketHolderFixture<TicketHolderImpl>> ticketHolder; static ServiceContext::UniqueServiceContext serviceContext; { stdx::unique_lock lk(isReadyMutex); @@ -87,9 +97,7 @@ void BM_acquireAndRelease(benchmark::State& state) { serviceContext = ServiceContext::make(); serviceContext->setTickSource(std::make_unique<TickSourceMock<Microseconds>>()); serviceContext->registerClientObserver(std::make_unique<LockerNoopClientObserver>()); - readTicketHolder = std::make_unique<TicketHolderFixture<TicketHolderImpl>>( - state.threads, serviceContext.get()); - writeTicketHolder = std::make_unique<TicketHolderFixture<TicketHolderImpl>>( + ticketHolder = std::make_unique<TicketHolderFixture<TicketHolderImpl>>( state.threads, serviceContext.get()); isReady = true; isReadyCv.notify_all(); @@ -98,14 +106,25 @@ void BM_acquireAndRelease(benchmark::State& state) { } } double acquired = 0; - auto mode = (state.thread_index % 2) == 0 ? MODE_IS : MODE_IX; - auto priority = (state.thread_index % 2) == 0 ? AdmissionContext::Priority::kLow - : AdmissionContext::Priority::kNormal; - TicketHolderFixture<TicketHolderImpl>* fixture; - fixture = (mode == MODE_IS ? readTicketHolder : writeTicketHolder).get(); + + AdmissionContext::Priority priority = [&] { + switch (admissionsPriority) { + case AdmissionsPriority::kNormal: + return AdmissionContext::Priority::kNormal; + case AdmissionsPriority::kLow: + return AdmissionContext::Priority::kLow; + case AdmissionsPriority::kNormalAndLow: { + return (state.thread_index % 2) == 0 ? AdmissionContext::Priority::kNormal + : AdmissionContext::Priority::kLow; + } + default: + MONGO_UNREACHABLE; + } + }(); + + TicketHolderFixture<TicketHolderImpl>* fixture = ticketHolder.get(); for (auto _ : state) { AdmissionContext admCtx; - admCtx.setLockMode(mode); admCtx.setPriority(priority); auto opCtx = fixture->opCtxs[state.thread_index].get(); { @@ -120,22 +139,44 @@ void BM_acquireAndRelease(benchmark::State& state) { state.counters["AcquiredPerThread"] = benchmark::Counter(acquired, benchmark::Counter::kAvgThreadsRate); if (state.thread_index == 0) { - readTicketHolder.reset(); - writeTicketHolder.reset(); + ticketHolder.reset(); serviceContext.reset(); isReady = false; } } -BENCHMARK_TEMPLATE(BM_acquireAndRelease, SemaphoreTicketHolder) +// The 'AdmissionsPriority' has no effect on SemaphoreTicketHolder performance because the +// SemaphoreTicketHolder treaats all operations the same, regardless of their specified priority. +// However, the benchmarks between the SemaphoreTicketHolder and the PriorityTicketHolder are only +// comparable when all admissions are of normal priority. +BENCHMARK_TEMPLATE(BM_acquireAndRelease, SemaphoreTicketHolder, AdmissionsPriority::kNormal) ->Threads(kThreadMin) ->Threads(kTickets) ->Threads(kThreadMax); -BENCHMARK_TEMPLATE(BM_acquireAndRelease, PriorityTicketHolder) +BENCHMARK_TEMPLATE(BM_acquireAndRelease, PriorityTicketHolder, AdmissionsPriority::kNormal) ->Threads(kThreadMin) ->Threads(kTickets) ->Threads(kThreadMax); +// Low priority operations are expected to take longer to acquire a ticket because they are forced +// to take a slower path than normal priority operations. +BENCHMARK_TEMPLATE(BM_acquireAndRelease, PriorityTicketHolder, AdmissionsPriority::kLow) + ->Threads(kThreadMin) + ->Threads(kTickets) + ->Threads(kThreadMax); + +// This benchmark is intended for comparisons between different iterations of the +// PriorityTicketHolder over time. +// +// Since it is known low priority operations will be less performant than normal priority +// operations, the aggregate performance over operations will be lower, and cannot be accurately +// compared to TicketHolderImpl benchmarks with only normal priority operations. +BENCHMARK_TEMPLATE(BM_acquireAndRelease, PriorityTicketHolder, AdmissionsPriority::kNormalAndLow) + ->Threads(kThreadMin) + ->Threads(kTickets) + ->Threads(kThreadMax); + + } // namespace } // namespace mongo |