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 = 180000;
53 const size_t kRcuNoSyncPassCount = 3500000;
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 (int write_percentage = 1; write_percentage <= 5; write_percentage += 1) {
69 for (size_t count = 0; count < pass_count; count++) {
70 for (int i = 0; i < 100; ++i) {
71 if (i < write_percentage) {
72 RcuFoo* f = new RcuFoo();
74 folly::synchronize_rcu();
82 auto finish_time = std::chrono::system_clock::now();
83 auto dur = finish_time - start_time;
84 auto milisecs = std::chrono::duration_cast<std::chrono::milliseconds>(dur);
85 std::cout << "[ OK ] " << kTestName << "." << bench_name
86 << " (" << milisecs.count() << " ms)" << std::endl;
89 void run_rcu_no_sync(size_t pass_count, const char* bench_name) {
90 std::cout << "[ RUN ] " << kTestName << "." << bench_name << std::endl;
91 auto start_time = std::chrono::system_clock::now();
93 for (int write_percentage = 1; write_percentage <= 5; write_percentage += 1) {
94 for (size_t count = 0; count < pass_count; count++) {
95 for (int i = 0; i < 100; ++i) {
96 if (i < write_percentage) {
97 RcuFoo* f = new RcuFoo();
106 auto finish_time = std::chrono::system_clock::now();
107 auto dur = finish_time - start_time;
108 auto milisecs = std::chrono::duration_cast<std::chrono::milliseconds>(dur);
109 std::cout << "[ OK ] " << kTestName << "." << bench_name
110 << " (" << milisecs.count() << " ms)" << std::endl;
113 template <typename Lock>
114 void run_rw_lock(size_t pass_count, const char* bench_name) {
115 std::cout << "[ RUN ] " << kTestName << "." << bench_name << std::endl;
116 auto start_time = std::chrono::system_clock::now();
118 std::unique_ptr<Lock> l(new Lock());
119 for (int write_percentage = 5; write_percentage < 20; write_percentage += 5) {
120 for (size_t count = 0; count < pass_count; count++) {
121 for (int i = 0; i < 100; ++i) {
122 if (i < write_percentage) {
133 auto finish_time = std::chrono::system_clock::now();
134 auto dur = finish_time - start_time;
135 auto milisecs = std::chrono::duration_cast<std::chrono::milliseconds>(dur);
136 std::cout << "[ OK ] " << kTestName << "." << bench_name
137 << " (" << milisecs.count() << " ms)" << std::endl;
140 template <typename Lock>
141 void run_small_lock(Lock* l, size_t pass_count, const char* bench_name) {
142 std::cout << "[ RUN ] " << kTestName << "." << bench_name << std::endl;
143 auto start_time = std::chrono::system_clock::now();
145 for (size_t count = 0; count < pass_count; count++) {
149 auto finish_time = std::chrono::system_clock::now();
150 auto dur = finish_time - start_time;
151 auto milisecs = std::chrono::duration_cast<std::chrono::milliseconds>(dur);
152 std::cout << "[ OK ] " << kTestName << "." << bench_name
153 << " (" << milisecs.count() << " ms)" << std::endl;
156 template <typename Lock>
157 void init_run_lock(size_t pass_count, const char* bench_name) {
158 std::unique_ptr<Lock> l(new Lock());
160 run_small_lock<Lock>(l.get(), pass_count, bench_name);
164 run_rcu_sync(kRcuSyncPassCount, kRcuSyncBenchmarkName);
165 run_rcu_no_sync(kRcuNoSyncPassCount, kRcuNoSyncBenchmarkName);
167 run_rw_lock<RWTicketSpinLock32>(kRWTicketSpinLockPassCount,
168 kRWTicketSpinLock32BenchmarkName);
169 run_rw_lock<RWTicketSpinLock64>(kRWTicketSpinLockPassCount,
170 kRWTicketSpinLock64BenchmarkName);
172 run_rw_lock<RWSpinLock>(kRWSpinLockPassCount, kRWSpinLockBenchmarkName);
174 run_rw_lock<SharedMutexReadPriority>(
175 kSharedMutexPassCount, kSharedMutexReadPriorityBenchmarkName);
176 run_rw_lock<SharedMutexWritePriority>(
177 kSharedMutexPassCount, kSharedMutexWritePriorityBenchmarkName);
179 init_run_lock<MicroSpinLock>(kMicroSpinLockPassCount,
180 kMicroSpinLockBenchmarkName);
181 init_run_lock<PicoSpinLock>(kPicoSpinLockPassCount,
182 kPicoSpinLockBenchmarkName);
183 init_run_lock<MicroLock>(kMicroLockPassCount, kMicroLockBenchmarkName);