[libcxx-commits] [libcxx] [libc++] Split std::hash benchmark out of std::unordered_set benchmark (PR #114448)
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Oct 31 11:36:30 PDT 2024
https://github.com/ldionne created https://github.com/llvm/llvm-project/pull/114448
As a drive-by, remove unused functor inside the unordered_set benchmark. That benchmark isn't very exhaustive, but that can be addressed separately.
>From c101d2f195adb28b0eece3ba8f14c6d19193fa23 Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Thu, 31 Oct 2024 14:29:15 -0400
Subject: [PATCH] [libc++] Split std::hash benchmark out of std::unordered_set
benchmark
As a drive-by, remove unused functor inside the unordered_set benchmark.
That benchmark isn't very exhaustive, but that can be addressed separately.
---
libcxx/test/benchmarks/CMakeLists.txt | 1 +
libcxx/test/benchmarks/hash.bench.cpp | 80 +++++++++++++++++++
.../unordered_set_operations.bench.cpp | 37 ---------
3 files changed, 81 insertions(+), 37 deletions(-)
create mode 100644 libcxx/test/benchmarks/hash.bench.cpp
diff --git a/libcxx/test/benchmarks/CMakeLists.txt b/libcxx/test/benchmarks/CMakeLists.txt
index b402af8d80dae8..5e829a639d39a5 100644
--- a/libcxx/test/benchmarks/CMakeLists.txt
+++ b/libcxx/test/benchmarks/CMakeLists.txt
@@ -157,6 +157,7 @@ set(BENCHMARK_TESTS
formatter_float.bench.cpp
formatter_int.bench.cpp
function.bench.cpp
+ hash.bench.cpp
join_view.bench.cpp
lexicographical_compare_three_way.bench.cpp
map.bench.cpp
diff --git a/libcxx/test/benchmarks/hash.bench.cpp b/libcxx/test/benchmarks/hash.bench.cpp
new file mode 100644
index 00000000000000..e0159874476293
--- /dev/null
+++ b/libcxx/test/benchmarks/hash.bench.cpp
@@ -0,0 +1,80 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+
+#include <cstdint>
+#include <cstddef>
+#include <functional>
+
+#include "benchmark/benchmark.h"
+
+#include "GenerateInput.h"
+#include "test_macros.h"
+
+constexpr std::size_t TestNumInputs = 1024;
+
+template <class _Size>
+inline TEST_ALWAYS_INLINE _Size loadword(const void* __p) {
+ _Size __r;
+ std::memcpy(&__r, __p, sizeof(__r));
+ return __r;
+}
+
+inline TEST_ALWAYS_INLINE std::size_t hash_len_16(std::size_t __u, std::size_t __v) {
+ const std::size_t __mul = 0x9ddfea08eb382d69ULL;
+ std::size_t __a = (__u ^ __v) * __mul;
+ __a ^= (__a >> 47);
+ std::size_t __b = (__v ^ __a) * __mul;
+ __b ^= (__b >> 47);
+ __b *= __mul;
+ return __b;
+}
+
+template <std::size_t _Len>
+inline TEST_ALWAYS_INLINE std::size_t hash_len_0_to_8(const char* __s) {
+ static_assert(_Len == 4 || _Len == 8, "");
+ const uint64_t __a = loadword<uint32_t>(__s);
+ const uint64_t __b = loadword<uint32_t>(__s + _Len - 4);
+ return hash_len_16(_Len + (__a << 3), __b);
+}
+
+struct UInt32Hash {
+ UInt32Hash() = default;
+ inline TEST_ALWAYS_INLINE std::size_t operator()(uint32_t data) const {
+ return hash_len_0_to_8<4>(reinterpret_cast<const char*>(&data));
+ }
+};
+
+template <class HashFn, class GenInputs>
+void BM_Hash(benchmark::State& st, HashFn fn, GenInputs gen) {
+ auto in = gen(st.range(0));
+ const auto end = in.data() + in.size();
+ std::size_t last_hash = 0;
+ benchmark::DoNotOptimize(&last_hash);
+ while (st.KeepRunning()) {
+ for (auto it = in.data(); it != end; ++it) {
+ benchmark::DoNotOptimize(last_hash += fn(*it));
+ }
+ benchmark::ClobberMemory();
+ }
+}
+
+BENCHMARK_CAPTURE(BM_Hash, uint32_random_std_hash, std::hash<uint32_t>{}, getRandomIntegerInputs<uint32_t>)
+ ->Arg(TestNumInputs);
+
+BENCHMARK_CAPTURE(BM_Hash, uint32_random_custom_hash, UInt32Hash{}, getRandomIntegerInputs<uint32_t>)
+ ->Arg(TestNumInputs);
+
+BENCHMARK_CAPTURE(BM_Hash, uint32_top_std_hash, std::hash<uint32_t>{}, getSortedTopBitsIntegerInputs<uint32_t>)
+ ->Arg(TestNumInputs);
+
+BENCHMARK_CAPTURE(BM_Hash, uint32_top_custom_hash, UInt32Hash{}, getSortedTopBitsIntegerInputs<uint32_t>)
+ ->Arg(TestNumInputs);
+
+BENCHMARK_MAIN();
diff --git a/libcxx/test/benchmarks/unordered_set_operations.bench.cpp b/libcxx/test/benchmarks/unordered_set_operations.bench.cpp
index bcf6adda2e0219..2e42d6d345b998 100644
--- a/libcxx/test/benchmarks/unordered_set_operations.bench.cpp
+++ b/libcxx/test/benchmarks/unordered_set_operations.bench.cpp
@@ -95,13 +95,6 @@ struct UInt32Hash2 {
}
};
-struct UInt64Hash2 {
- UInt64Hash2() = default;
- inline TEST_ALWAYS_INLINE std::size_t operator()(uint64_t data) const {
- return hash_len_0_to_8<8>(reinterpret_cast<const char*>(&data));
- }
-};
-
// The sole purpose of this comparator is to be used in BM_Rehash, where
// we need something slow enough to be easily noticable in benchmark results.
// The default implementation of operator== for strings seems to be a little
@@ -123,36 +116,6 @@ struct SlowStringEq {
}
};
-//----------------------------------------------------------------------------//
-// BM_Hash
-// ---------------------------------------------------------------------------//
-
-template <class HashFn, class GenInputs>
-void BM_Hash(benchmark::State& st, HashFn fn, GenInputs gen) {
- auto in = gen(st.range(0));
- const auto end = in.data() + in.size();
- std::size_t last_hash = 0;
- benchmark::DoNotOptimize(&last_hash);
- while (st.KeepRunning()) {
- for (auto it = in.data(); it != end; ++it) {
- benchmark::DoNotOptimize(last_hash += fn(*it));
- }
- benchmark::ClobberMemory();
- }
-}
-
-BENCHMARK_CAPTURE(BM_Hash, uint32_random_std_hash, std::hash<uint32_t>{}, getRandomIntegerInputs<uint32_t>)
- ->Arg(TestNumInputs);
-
-BENCHMARK_CAPTURE(BM_Hash, uint32_random_custom_hash, UInt32Hash{}, getRandomIntegerInputs<uint32_t>)
- ->Arg(TestNumInputs);
-
-BENCHMARK_CAPTURE(BM_Hash, uint32_top_std_hash, std::hash<uint32_t>{}, getSortedTopBitsIntegerInputs<uint32_t>)
- ->Arg(TestNumInputs);
-
-BENCHMARK_CAPTURE(BM_Hash, uint32_top_custom_hash, UInt32Hash{}, getSortedTopBitsIntegerInputs<uint32_t>)
- ->Arg(TestNumInputs);
-
//----------------------------------------------------------------------------//
// BM_InsertValue
// ---------------------------------------------------------------------------//
More information about the libcxx-commits
mailing list