1 #include <folly/SmallLocks.h>
2 #include <folly/RWSpinLock.h>
3 #include <folly/SharedMutex.h>
4 #include <folly/synchronization/Rcu.h>
13 const char* kTestName = "LockUnlock";
16 const size_t kMicroLockPassCount = 2000000000;
17 const char* kMicroLockBenchmarkName = "FollyMicroLock";
18 typedef folly::MicroLock MicroLock;
21 const size_t kMicroSpinLockPassCount = 1500000000;
22 const char* kMicroSpinLockBenchmarkName = "FollyMicroSpinLock";
23 typedef folly::MicroSpinLock MicroSpinLock;
26 const size_t kPicoSpinLockPassCount = 2700000000;
27 const char* kPicoSpinLockBenchmarkName = "FollyPicoSpinLock";
28 typedef folly::PicoSpinLock<size_t> PicoSpinLock;
31 const size_t kSharedMutexPassCount = 5000000;
32 const char* kSharedMutexReadPriorityBenchmarkName =
33 "FollySharedMutex_ReadPriority";
34 const char* kSharedMutexWritePriorityBenchmarkName =
35 "FollySharedMutex_WritePriority";
36 typedef folly::SharedMutexReadPriority SharedMutexReadPriority;
37 typedef folly::SharedMutexWritePriority SharedMutexWritePriority;
40 const size_t kRWSpinLockPassCount = 5000000;
41 const char* kRWSpinLockBenchmarkName = "FollyRWSpinLock";
42 typedef folly::RWSpinLock RWSpinLock;
45 const size_t kRWTicketSpinLockPassCount = 5000000;
46 const char* kRWTicketSpinLock32BenchmarkName = "FollyRWTicketSpinLock_32";
47 const char* kRWTicketSpinLock64BenchmarkName = "FollyRWTicketSpinLock_64";
48 typedef folly::RWTicketSpinLock32 RWTicketSpinLock32;
49 typedef folly::RWTicketSpinLock64 RWTicketSpinLock64;
52 const size_t kRcuSyncPassCount = 3000000;
53 const size_t kRcuNoSyncPassCount = 2500000;
54 const char* kRcuSyncBenchmarkName = "FollyRCU_Sync";
55 const char* kRcuNoSyncBenchmarkName = "FollyRCU_NoSync";
56 // Represent the RCU-protected data.
64 void run_rcu_sync(size_t pass_count, const char* bench_name) {
65 std::cout << "[ RUN ] " << kTestName << "." << bench_name << std::endl;
66 auto start_time = std::chrono::system_clock::now();
68 for (size_t count = 0; count < pass_count; count++) {
69 RcuFoo* f = new RcuFoo();
71 folly::synchronize_rcu();
74 auto finish_time = std::chrono::system_clock::now();
75 auto dur = finish_time - start_time;
76 auto milisecs = std::chrono::duration_cast<std::chrono::milliseconds>(dur);
77 std::cout << "[ OK ] " << kTestName << "." << bench_name
78 << " (" << milisecs.count() << " ms)" << std::endl;
81 void run_rcu_no_sync(size_t pass_count, const char* bench_name) {
82 std::cout << "[ RUN ] " << kTestName << "." << bench_name << std::endl;
83 auto start_time = std::chrono::system_clock::now();
85 for (int write_percentage = 5; write_percentage <= 10; write_percentage += 1) {
86 for (size_t count = 0; count < pass_count; count++) {
87 for (int i = 0; i < 100; ++i) {
88 if (i < write_percentage) {
89 RcuFoo* f = new RcuFoo();
98 auto finish_time = std::chrono::system_clock::now();
99 auto dur = finish_time - start_time;
100 auto milisecs = std::chrono::duration_cast<std::chrono::milliseconds>(dur);
101 std::cout << "[ OK ] " << kTestName << "." << bench_name
102 << " (" << milisecs.count() << " ms)" << std::endl;
105 template <typename Lock>
106 void run_rw_lock(size_t pass_count, const char* bench_name) {
107 std::cout << "[ RUN ] " << kTestName << "." << bench_name << std::endl;
108 auto start_time = std::chrono::system_clock::now();
110 std::unique_ptr<Lock> l(new Lock());
111 for (int write_percentage = 5; write_percentage < 20; write_percentage += 5) {
112 for (size_t count = 0; count < pass_count; count++) {
113 for (int i = 0; i < 100; ++i) {
114 if (i < write_percentage) {
125 auto finish_time = std::chrono::system_clock::now();
126 auto dur = finish_time - start_time;
127 auto milisecs = std::chrono::duration_cast<std::chrono::milliseconds>(dur);
128 std::cout << "[ OK ] " << kTestName << "." << bench_name
129 << " (" << milisecs.count() << " ms)" << std::endl;
132 template <typename Lock>
133 void run_small_lock(Lock* l, size_t pass_count, const char* bench_name) {
134 std::cout << "[ RUN ] " << kTestName << "." << bench_name << std::endl;
135 auto start_time = std::chrono::system_clock::now();
137 for (size_t count = 0; count < pass_count; count++) {
141 auto finish_time = std::chrono::system_clock::now();
142 auto dur = finish_time - start_time;
143 auto milisecs = std::chrono::duration_cast<std::chrono::milliseconds>(dur);
144 std::cout << "[ OK ] " << kTestName << "." << bench_name
145 << " (" << milisecs.count() << " ms)" << std::endl;
148 template <typename Lock>
149 void init_run_lock(size_t pass_count, const char* bench_name) {
150 std::unique_ptr<Lock> l(new Lock());
152 run_small_lock<Lock>(l.get(), pass_count, bench_name);
156 run_rcu_sync(kRcuSyncPassCount, kRcuSyncBenchmarkName);
157 run_rcu_no_sync(kRcuNoSyncPassCount, kRcuNoSyncBenchmarkName);
159 run_rw_lock<RWTicketSpinLock32>(kRWTicketSpinLockPassCount,
160 kRWTicketSpinLock32BenchmarkName);
161 run_rw_lock<RWTicketSpinLock64>(kRWTicketSpinLockPassCount,
162 kRWTicketSpinLock64BenchmarkName);
164 run_rw_lock<RWSpinLock>(kRWSpinLockPassCount, kRWSpinLockBenchmarkName);
166 run_rw_lock<SharedMutexReadPriority>(
167 kSharedMutexPassCount, kSharedMutexReadPriorityBenchmarkName);
168 run_rw_lock<SharedMutexWritePriority>(
169 kSharedMutexPassCount, kSharedMutexWritePriorityBenchmarkName);
171 init_run_lock<MicroSpinLock>(kMicroSpinLockPassCount,
172 kMicroSpinLockBenchmarkName);
173 init_run_lock<PicoSpinLock>(kPicoSpinLockPassCount,
174 kPicoSpinLockBenchmarkName);
175 init_run_lock<MicroLock>(kMicroLockPassCount, kMicroLockBenchmarkName);