[libcxx-commits] [libcxx] [tzdb] Replace shared_mutex with mutex. (PR #87929)
via libcxx-commits
libcxx-commits at lists.llvm.org
Sun Apr 7 10:02:36 PDT 2024
https://github.com/EricWF updated https://github.com/llvm/llvm-project/pull/87929
>From ea4795778633c06815e73cfa307bbb7ededc14f1 Mon Sep 17 00:00:00 2001
From: Eric Fiselier <eric at efcs.ca>
Date: Sun, 7 Apr 2024 12:53:04 -0400
Subject: [PATCH 1/2] [tzdb] Replace shared_mutex with mutex.
The overhead of taking a std::mutex is much lower than taking a reader
lock on a shared mutex, even under heavy contention.
The benifit of shared_mutex only occurs as the amount of
time spent in the critical sections grows large enough.
In our case all we do is read a pointer and return the lock.
As a result, using a shared lock can be ~50%-100% slower
---
libcxx/benchmarks/CMakeLists.txt | 1 +
.../shared_mutex_vs_mutex.bench.cpp | 41 +++++++++++++++++++
libcxx/src/include/tzdb/tzdb_list_private.h | 8 ++--
3 files changed, 46 insertions(+), 4 deletions(-)
create mode 100644 libcxx/benchmarks/shared_mutex_vs_mutex.bench.cpp
diff --git a/libcxx/benchmarks/CMakeLists.txt b/libcxx/benchmarks/CMakeLists.txt
index 928238c1ac69ba..527a2acf2d3b36 100644
--- a/libcxx/benchmarks/CMakeLists.txt
+++ b/libcxx/benchmarks/CMakeLists.txt
@@ -221,6 +221,7 @@ set(BENCHMARK_TESTS
map.bench.cpp
monotonic_buffer.bench.cpp
ordered_set.bench.cpp
+ shared_mutex_vs_mutex.bench.cpp
stop_token.bench.cpp
std_format_spec_string_unicode.bench.cpp
string.bench.cpp
diff --git a/libcxx/benchmarks/shared_mutex_vs_mutex.bench.cpp b/libcxx/benchmarks/shared_mutex_vs_mutex.bench.cpp
new file mode 100644
index 00000000000000..7d06857d0ad6e7
--- /dev/null
+++ b/libcxx/benchmarks/shared_mutex_vs_mutex.bench.cpp
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// This benchmark compares the performance of std::mutex and std::shared_mutex in contended scenarios.
+// it's meant to establish a baseline overhead for std::shared_mutex and std::mutex, and to help inform decisions about
+// which mutex to use when selecting a mutex type for a given use case.
+
+#include <atomic>
+#include <mutex>
+#include <numeric>
+#include <thread>
+#include <shared_mutex>
+
+#include "benchmark/benchmark.h"
+
+int global_value = 42;
+std::mutex m;
+std::shared_mutex sm;
+
+static void BM_shared_mutex(benchmark::State& state) {
+ for (auto _ : state) {
+ std::shared_lock<std::shared_mutex> lock(sm);
+ benchmark::DoNotOptimize(global_value);
+ }
+}
+
+static void BM_mutex(benchmark::State& state) {
+ for (auto _ : state) {
+ std::lock_guard<std::mutex> lock(m);
+ benchmark::DoNotOptimize(global_value);
+ }
+}
+
+BENCHMARK(BM_shared_mutex)->Threads(1)->Threads(2)->Threads(4)->Threads(8)->Threads(32);
+BENCHMARK(BM_mutex)->Threads(1)->Threads(2)->Threads(4)->Threads(8)->Threads(32);
+
+BENCHMARK_MAIN();
diff --git a/libcxx/src/include/tzdb/tzdb_list_private.h b/libcxx/src/include/tzdb/tzdb_list_private.h
index 969b2b9f8a9f63..c0598cb6e24b16 100644
--- a/libcxx/src/include/tzdb/tzdb_list_private.h
+++ b/libcxx/src/include/tzdb/tzdb_list_private.h
@@ -16,7 +16,7 @@
// When threads are not available the locking is not required.
#ifndef _LIBCPP_HAS_NO_THREADS
-# include <shared_mutex>
+# include <mutex>
#endif
#include "types_private.h"
@@ -56,7 +56,7 @@ class tzdb_list::__impl {
const tzdb& __front() const noexcept {
#ifndef _LIBCPP_HAS_NO_THREADS
- shared_lock __lock{__mutex_};
+ unique_lock __lock{__mutex_};
#endif
return __tzdb_.front();
}
@@ -72,7 +72,7 @@ class tzdb_list::__impl {
const_iterator __begin() const noexcept {
#ifndef _LIBCPP_HAS_NO_THREADS
- shared_lock __lock{__mutex_};
+ unique_lock __lock{__mutex_};
#endif
return __tzdb_.begin();
}
@@ -87,7 +87,7 @@ class tzdb_list::__impl {
void __load_no_lock() { chrono::__init_tzdb(__tzdb_.emplace_front(), __rules_.emplace_front()); }
#ifndef _LIBCPP_HAS_NO_THREADS
- mutable shared_mutex __mutex_;
+ mutable mutex __mutex_;
#endif
forward_list<tzdb> __tzdb_;
>From 4c233a02a0c2ca76ec265da6740c1700a24a0dbd Mon Sep 17 00:00:00 2001
From: Eric Fiselier <eric at efcs.ca>
Date: Sun, 7 Apr 2024 13:02:27 -0400
Subject: [PATCH 2/2] respect the formatter
---
libcxx/benchmarks/shared_mutex_vs_mutex.bench.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libcxx/benchmarks/shared_mutex_vs_mutex.bench.cpp b/libcxx/benchmarks/shared_mutex_vs_mutex.bench.cpp
index 7d06857d0ad6e7..19d13b799cc137 100644
--- a/libcxx/benchmarks/shared_mutex_vs_mutex.bench.cpp
+++ b/libcxx/benchmarks/shared_mutex_vs_mutex.bench.cpp
@@ -12,8 +12,8 @@
#include <atomic>
#include <mutex>
#include <numeric>
-#include <thread>
#include <shared_mutex>
+#include <thread>
#include "benchmark/benchmark.h"
More information about the libcxx-commits
mailing list