2 * Copyright 2016 Facebook, Inc.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include <folly/ThreadLocal.h>
19 #include <sys/types.h>
24 #include <condition_variable>
30 #include <unordered_map>
32 #include <boost/thread/tss.hpp>
33 #include <glog/logging.h>
35 #include <folly/Benchmark.h>
36 #include <folly/experimental/io/FsUtil.h>
37 #include <folly/portability/GFlags.h>
38 #include <folly/portability/Unistd.h>
40 using namespace folly;
42 // Simple reference implementation using pthread_get_specific
44 class PThreadGetSpecific {
46 PThreadGetSpecific() : key_(0) { pthread_key_create(&key_, OnThreadExit); }
48 T* get() const { return static_cast<T*>(pthread_getspecific(key_)); }
52 pthread_setspecific(key_, t);
54 static void OnThreadExit(void* obj) { delete static_cast<T*>(obj); }
60 DEFINE_int32(numThreads, 8, "Number simultaneous threads for benchmarks.");
63 BENCHMARK(FB_CONCATENATE(BM_mt_, var), iters) { \
64 const int itersPerThread = iters / FLAGS_numThreads; \
65 std::vector<std::thread> threads; \
66 for (int i = 0; i < FLAGS_numThreads; ++i) { \
67 threads.push_back(std::thread([&]() { \
68 var.reset(new int(0)); \
69 for (int i = 0; i < itersPerThread; ++i) { \
74 for (auto& t : threads) { \
79 ThreadLocalPtr<int> tlp;
81 PThreadGetSpecific<int> pthread_get_specific;
82 REG(pthread_get_specific);
83 boost::thread_specific_ptr<int> boost_tsp;
85 BENCHMARK_DRAW_LINE();
87 int main(int argc, char** argv) {
88 gflags::ParseCommandLineFlags(&argc, &argv, true);
89 gflags::SetCommandLineOptionWithMode(
90 "bm_max_iters", "100000000", gflags::SET_FLAG_IF_DEFAULT);
91 folly::runBenchmarks();
96 Ran with 24 threads on dual 12-core Xeon(R) X5650 @ 2.67GHz with 12-MB caches
98 Benchmark Iters Total t t/iter iter/sec
99 ------------------------------------------------------------------------------
100 * BM_mt_tlp 100000000 39.88 ms 398.8 ps 2.335 G
101 +5.91% BM_mt_pthread_get_specific 100000000 42.23 ms 422.3 ps 2.205 G
102 + 295% BM_mt_boost_tsp 100000000 157.8 ms 1.578 ns 604.5 M
103 ------------------------------------------------------------------------------