1*9356374aSAndroid Build Coastguard Worker // Copyright 2021 The Abseil Authors. 2*9356374aSAndroid Build Coastguard Worker // 3*9356374aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License"); 4*9356374aSAndroid Build Coastguard Worker // you may not use this file except in compliance with the License. 5*9356374aSAndroid Build Coastguard Worker // You may obtain a copy of the License at 6*9356374aSAndroid Build Coastguard Worker // 7*9356374aSAndroid Build Coastguard Worker // https://www.apache.org/licenses/LICENSE-2.0 8*9356374aSAndroid Build Coastguard Worker // 9*9356374aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software 10*9356374aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS, 11*9356374aSAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*9356374aSAndroid Build Coastguard Worker // See the License for the specific language governing permissions and 13*9356374aSAndroid Build Coastguard Worker // limitations under the License. 14*9356374aSAndroid Build Coastguard Worker 15*9356374aSAndroid Build Coastguard Worker #include <limits> 16*9356374aSAndroid Build Coastguard Worker 17*9356374aSAndroid Build Coastguard Worker #include "absl/base/no_destructor.h" 18*9356374aSAndroid Build Coastguard Worker #include "absl/synchronization/blocking_counter.h" 19*9356374aSAndroid Build Coastguard Worker #include "absl/synchronization/internal/thread_pool.h" 20*9356374aSAndroid Build Coastguard Worker #include "benchmark/benchmark.h" 21*9356374aSAndroid Build Coastguard Worker 22*9356374aSAndroid Build Coastguard Worker namespace { 23*9356374aSAndroid Build Coastguard Worker BM_BlockingCounter_SingleThread(benchmark::State & state)24*9356374aSAndroid Build Coastguard Workervoid BM_BlockingCounter_SingleThread(benchmark::State& state) { 25*9356374aSAndroid Build Coastguard Worker for (auto _ : state) { 26*9356374aSAndroid Build Coastguard Worker int iterations = state.range(0); 27*9356374aSAndroid Build Coastguard Worker absl::BlockingCounter counter{iterations}; 28*9356374aSAndroid Build Coastguard Worker for (int i = 0; i < iterations; ++i) { 29*9356374aSAndroid Build Coastguard Worker counter.DecrementCount(); 30*9356374aSAndroid Build Coastguard Worker } 31*9356374aSAndroid Build Coastguard Worker counter.Wait(); 32*9356374aSAndroid Build Coastguard Worker } 33*9356374aSAndroid Build Coastguard Worker } 34*9356374aSAndroid Build Coastguard Worker BENCHMARK(BM_BlockingCounter_SingleThread) 35*9356374aSAndroid Build Coastguard Worker ->ArgName("iterations") 36*9356374aSAndroid Build Coastguard Worker ->Arg(2) 37*9356374aSAndroid Build Coastguard Worker ->Arg(4) 38*9356374aSAndroid Build Coastguard Worker ->Arg(16) 39*9356374aSAndroid Build Coastguard Worker ->Arg(64) 40*9356374aSAndroid Build Coastguard Worker ->Arg(256); 41*9356374aSAndroid Build Coastguard Worker BM_BlockingCounter_DecrementCount(benchmark::State & state)42*9356374aSAndroid Build Coastguard Workervoid BM_BlockingCounter_DecrementCount(benchmark::State& state) { 43*9356374aSAndroid Build Coastguard Worker static absl::NoDestructor<absl::BlockingCounter> counter( 44*9356374aSAndroid Build Coastguard Worker std::numeric_limits<int>::max()); 45*9356374aSAndroid Build Coastguard Worker for (auto _ : state) { 46*9356374aSAndroid Build Coastguard Worker counter->DecrementCount(); 47*9356374aSAndroid Build Coastguard Worker } 48*9356374aSAndroid Build Coastguard Worker } 49*9356374aSAndroid Build Coastguard Worker BENCHMARK(BM_BlockingCounter_DecrementCount) 50*9356374aSAndroid Build Coastguard Worker ->Threads(2) 51*9356374aSAndroid Build Coastguard Worker ->Threads(4) 52*9356374aSAndroid Build Coastguard Worker ->Threads(6) 53*9356374aSAndroid Build Coastguard Worker ->Threads(8) 54*9356374aSAndroid Build Coastguard Worker ->Threads(10) 55*9356374aSAndroid Build Coastguard Worker ->Threads(12) 56*9356374aSAndroid Build Coastguard Worker ->Threads(16) 57*9356374aSAndroid Build Coastguard Worker ->Threads(32) 58*9356374aSAndroid Build Coastguard Worker ->Threads(64) 59*9356374aSAndroid Build Coastguard Worker ->Threads(128); 60*9356374aSAndroid Build Coastguard Worker BM_BlockingCounter_Wait(benchmark::State & state)61*9356374aSAndroid Build Coastguard Workervoid BM_BlockingCounter_Wait(benchmark::State& state) { 62*9356374aSAndroid Build Coastguard Worker int num_threads = state.range(0); 63*9356374aSAndroid Build Coastguard Worker absl::synchronization_internal::ThreadPool pool(num_threads); 64*9356374aSAndroid Build Coastguard Worker for (auto _ : state) { 65*9356374aSAndroid Build Coastguard Worker absl::BlockingCounter counter{num_threads}; 66*9356374aSAndroid Build Coastguard Worker pool.Schedule([num_threads, &counter, &pool]() { 67*9356374aSAndroid Build Coastguard Worker for (int i = 0; i < num_threads; ++i) { 68*9356374aSAndroid Build Coastguard Worker pool.Schedule([&counter]() { counter.DecrementCount(); }); 69*9356374aSAndroid Build Coastguard Worker } 70*9356374aSAndroid Build Coastguard Worker }); 71*9356374aSAndroid Build Coastguard Worker counter.Wait(); 72*9356374aSAndroid Build Coastguard Worker } 73*9356374aSAndroid Build Coastguard Worker } 74*9356374aSAndroid Build Coastguard Worker BENCHMARK(BM_BlockingCounter_Wait) 75*9356374aSAndroid Build Coastguard Worker ->ArgName("threads") 76*9356374aSAndroid Build Coastguard Worker ->Arg(2) 77*9356374aSAndroid Build Coastguard Worker ->Arg(4) 78*9356374aSAndroid Build Coastguard Worker ->Arg(8) 79*9356374aSAndroid Build Coastguard Worker ->Arg(16) 80*9356374aSAndroid Build Coastguard Worker ->Arg(32) 81*9356374aSAndroid Build Coastguard Worker ->Arg(64) 82*9356374aSAndroid Build Coastguard Worker ->Arg(128); 83*9356374aSAndroid Build Coastguard Worker 84*9356374aSAndroid Build Coastguard Worker } // namespace 85