1 /*
2  * Copyright (c) Facebook, Inc. and its affiliates.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <thread>
18 
19 #include <folly/Benchmark.h>
20 #include <folly/experimental/TLRefCount.h>
21 
22 namespace folly {
23 
24 template <typename Counter>
shutdown(Counter &)25 void shutdown(Counter&) {}
26 
shutdown(TLRefCount & c)27 void shutdown(TLRefCount& c) {
28   c.useGlobal();
29   --c;
30 }
31 
32 template <typename Counter, size_t threadCount>
benchmark(size_t n)33 void benchmark(size_t n) {
34   Counter x;
35 
36   std::vector<std::thread> ts;
37 
38   for (size_t t = 0; t < threadCount; ++t) {
39     ts.emplace_back([&]() {
40       for (size_t i = 0; i < n; ++i) {
41         ++x;
42       }
43       for (size_t i = 0; i < n; ++i) {
44         --x;
45       }
46     });
47   }
48 
49   for (auto& t : ts) {
50     t.join();
51   }
52 
53   shutdown(x);
54 }
55 
BENCHMARK(TLRefCountOneThread,n)56 BENCHMARK(TLRefCountOneThread, n) {
57   benchmark<TLRefCount, 1>(n);
58 }
59 
BENCHMARK(TLRefCountFourThreads,n)60 BENCHMARK(TLRefCountFourThreads, n) {
61   benchmark<TLRefCount, 4>(n);
62 }
63 
BENCHMARK(TLRefCountTwentyFourThreads,n)64 BENCHMARK(TLRefCountTwentyFourThreads, n) {
65   benchmark<TLRefCount, 24>(n);
66 }
67 
BENCHMARK(AtomicOneThread,n)68 BENCHMARK(AtomicOneThread, n) {
69   benchmark<std::atomic<size_t>, 1>(n);
70 }
71 
BENCHMARK(AtomicFourThreads,n)72 BENCHMARK(AtomicFourThreads, n) {
73   benchmark<std::atomic<size_t>, 4>(n);
74 }
75 
BENCHMARK(AtomicTwentyFourThreads,n)76 BENCHMARK(AtomicTwentyFourThreads, n) {
77   benchmark<std::atomic<size_t>, 24>(n);
78 }
79 
80 } // namespace folly
81 
main(int argc,char ** argv)82 int main(int argc, char** argv) {
83   gflags::ParseCommandLineFlags(&argc, &argv, true);
84   gflags::SetCommandLineOptionWithMode(
85       "bm_min_usec", "100000", gflags::SET_FLAG_IF_DEFAULT);
86 
87   folly::runBenchmarks();
88 
89   return 0;
90 }
91