Skip to content

[libc++] Add benchmarks for copy algorithms #127328

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Feb 20, 2025

Conversation

ldionne
Copy link
Member

@ldionne ldionne commented Feb 15, 2025

This patch adds benchmarks for the copy family of algorithms (copy, copy_n, copy_if, copy_backward).

@ldionne ldionne requested a review from a team as a code owner February 15, 2025 14:43
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Feb 15, 2025
@llvmbot
Copy link
Member

llvmbot commented Feb 15, 2025

@llvm/pr-subscribers-libcxx

Author: Louis Dionne (ldionne)

Changes

This patch adds benchmarks for the copy family of algorithms (copy, copy_n, copy_if, copy_backward).


Patch is 21.31 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/127328.diff

6 Files Affected:

  • (removed) libcxx/test/benchmarks/algorithms/copy.bench.cpp (-89)
  • (removed) libcxx/test/benchmarks/algorithms/copy_backward.bench.cpp (-55)
  • (added) libcxx/test/benchmarks/algorithms/modifying/copy.bench.cpp (+84)
  • (added) libcxx/test/benchmarks/algorithms/modifying/copy_backward.bench.cpp (+86)
  • (added) libcxx/test/benchmarks/algorithms/modifying/copy_if.bench.cpp (+105)
  • (added) libcxx/test/benchmarks/algorithms/modifying/copy_n.bench.cpp (+83)
diff --git a/libcxx/test/benchmarks/algorithms/copy.bench.cpp b/libcxx/test/benchmarks/algorithms/copy.bench.cpp
deleted file mode 100644
index b6f0f15eb7703..0000000000000
--- a/libcxx/test/benchmarks/algorithms/copy.bench.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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, c++11, c++14, c++17, c++20
-
-#include <algorithm>
-#include <benchmark/benchmark.h>
-#include <vector>
-
-static void bm_ranges_copy_vb(benchmark::State& state, bool aligned) {
-  auto n = state.range();
-  std::vector<bool> in(n, true);
-  std::vector<bool> out(aligned ? n : n + 8);
-  benchmark::DoNotOptimize(&in);
-  auto dst = aligned ? out.begin() : out.begin() + 4;
-  for (auto _ : state) {
-    benchmark::DoNotOptimize(std::ranges::copy(in, dst));
-    benchmark::DoNotOptimize(&out);
-  }
-}
-
-static void bm_ranges_copy_n_vb(benchmark::State& state, bool aligned) {
-  auto n = state.range();
-  std::vector<bool> in(n, true);
-  std::vector<bool> out(aligned ? n : n + 8);
-  benchmark::DoNotOptimize(&in);
-  auto src = in.begin();
-  auto dst = aligned ? out.begin() : out.begin() + 4;
-  for (auto _ : state) {
-    benchmark::DoNotOptimize(std::ranges::copy_n(src, n, dst));
-    benchmark::DoNotOptimize(&out);
-  }
-}
-
-static void bm_copy_vb(benchmark::State& state, bool aligned) {
-  auto n = state.range();
-  std::vector<bool> in(n, true);
-  std::vector<bool> out(aligned ? n : n + 8);
-  benchmark::DoNotOptimize(&in);
-  auto beg = in.begin();
-  auto end = in.end();
-  auto dst = aligned ? out.begin() : out.begin() + 4;
-  for (auto _ : state) {
-    benchmark::DoNotOptimize(std::copy(beg, end, dst));
-    benchmark::DoNotOptimize(&out);
-  }
-}
-
-static void bm_copy_n_vb(benchmark::State& state, bool aligned) {
-  auto n = state.range();
-  std::vector<bool> in(n, true);
-  std::vector<bool> out(aligned ? n : n + 8);
-  benchmark::DoNotOptimize(&in);
-  auto src = in.begin();
-  auto dst = aligned ? out.begin() : out.begin() + 4;
-  for (auto _ : state) {
-    benchmark::DoNotOptimize(std::copy_n(src, n, dst));
-    benchmark::DoNotOptimize(&out);
-  }
-}
-
-static void bm_ranges_copy_vb_aligned(benchmark::State& state) { bm_ranges_copy_vb(state, true); }
-static void bm_ranges_copy_vb_unaligned(benchmark::State& state) { bm_ranges_copy_vb(state, false); }
-static void bm_ranges_copy_n_vb_aligned(benchmark::State& state) { bm_ranges_copy_n_vb(state, true); }
-static void bm_ranges_copy_n_vb_unaligned(benchmark::State& state) { bm_ranges_copy_n_vb(state, false); }
-
-static void bm_copy_vb_aligned(benchmark::State& state) { bm_copy_vb(state, true); }
-static void bm_copy_vb_unaligned(benchmark::State& state) { bm_copy_vb(state, false); }
-static void bm_copy_n_vb_aligned(benchmark::State& state) { bm_copy_n_vb(state, true); }
-static void bm_copy_n_vb_unaligned(benchmark::State& state) { bm_copy_n_vb(state, false); }
-
-// Test std::ranges::copy for vector<bool>::iterator
-BENCHMARK(bm_ranges_copy_vb_aligned)->Range(8, 1 << 16)->DenseRange(102400, 204800, 4096);
-BENCHMARK(bm_ranges_copy_n_vb_aligned)->Range(8, 1 << 20);
-BENCHMARK(bm_ranges_copy_vb_unaligned)->Range(8, 1 << 20);
-BENCHMARK(bm_ranges_copy_n_vb_unaligned)->Range(8, 1 << 20);
-
-// Test std::copy for vector<bool>::iterator
-BENCHMARK(bm_copy_vb_aligned)->Range(8, 1 << 20);
-BENCHMARK(bm_copy_n_vb_aligned)->Range(8, 1 << 20);
-BENCHMARK(bm_copy_vb_unaligned)->Range(8, 1 << 20);
-BENCHMARK(bm_copy_n_vb_unaligned)->Range(8, 1 << 20);
-
-BENCHMARK_MAIN();
diff --git a/libcxx/test/benchmarks/algorithms/copy_backward.bench.cpp b/libcxx/test/benchmarks/algorithms/copy_backward.bench.cpp
deleted file mode 100644
index c943d9a874b49..0000000000000
--- a/libcxx/test/benchmarks/algorithms/copy_backward.bench.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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, c++11, c++14, c++17, c++20
-
-#include <algorithm>
-#include <benchmark/benchmark.h>
-#include <vector>
-
-static void bm_ranges_copy_backward_vb(benchmark::State& state, bool aligned) {
-  auto n = state.range();
-  std::vector<bool> in(n, true);
-  std::vector<bool> out(aligned ? n : n + 8);
-  benchmark::DoNotOptimize(&in);
-  auto dst = aligned ? out.end() : out.end() - 4;
-  for (auto _ : state) {
-    benchmark::DoNotOptimize(std::ranges::copy_backward(in, dst));
-    benchmark::DoNotOptimize(&out);
-  }
-}
-
-static void bm_copy_backward_vb(benchmark::State& state, bool aligned) {
-  auto n = state.range();
-  std::vector<bool> in(n, true);
-  std::vector<bool> out(aligned ? n : n + 8);
-  benchmark::DoNotOptimize(&in);
-  auto beg = in.begin();
-  auto end = in.end();
-  auto dst = aligned ? out.end() : out.end() - 4;
-  for (auto _ : state) {
-    benchmark::DoNotOptimize(std::copy_backward(beg, end, dst));
-    benchmark::DoNotOptimize(&out);
-  }
-}
-
-static void bm_ranges_copy_backward_vb_aligned(benchmark::State& state) { bm_ranges_copy_backward_vb(state, true); }
-static void bm_ranges_copy_backward_vb_unaligned(benchmark::State& state) { bm_ranges_copy_backward_vb(state, false); }
-
-static void bm_copy_backward_vb_aligned(benchmark::State& state) { bm_copy_backward_vb(state, true); }
-static void bm_copy_backward_vb_unaligned(benchmark::State& state) { bm_copy_backward_vb(state, false); }
-
-// Test std::ranges::copy_backward for vector<bool>::iterator
-BENCHMARK(bm_ranges_copy_backward_vb_aligned)->Range(8, 1 << 16)->DenseRange(102400, 204800, 4096);
-BENCHMARK(bm_ranges_copy_backward_vb_unaligned)->Range(8, 1 << 20);
-
-// Test std::copy_backward for vector<bool>::iterator
-BENCHMARK(bm_copy_backward_vb_aligned)->Range(8, 1 << 20);
-BENCHMARK(bm_copy_backward_vb_unaligned)->Range(8, 1 << 20);
-
-BENCHMARK_MAIN();
diff --git a/libcxx/test/benchmarks/algorithms/modifying/copy.bench.cpp b/libcxx/test/benchmarks/algorithms/modifying/copy.bench.cpp
new file mode 100644
index 0000000000000..dea1e9f5d7c34
--- /dev/null
+++ b/libcxx/test/benchmarks/algorithms/modifying/copy.bench.cpp
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++11, c++14, c++17
+
+#include <algorithm>
+#include <deque>
+#include <iterator>
+#include <list>
+#include <string>
+#include <vector>
+
+#include "benchmark/benchmark.h"
+#include "../../GenerateInput.h"
+
+template <class Container, class Operation>
+void bm_general(std::string operation_name, Operation copy) {
+  auto bench = [copy](auto& st) {
+    auto const size = st.range(0);
+    using ValueType = typename Container::value_type;
+    Container c;
+    std::generate_n(std::back_inserter(c), size, [] { return Generate<ValueType>::random(); });
+
+    std::vector<ValueType> out(size);
+
+    for ([[maybe_unused]] auto _ : st) {
+      auto result = copy(c.begin(), c.end(), out.begin());
+      benchmark::DoNotOptimize(result);
+      benchmark::DoNotOptimize(out);
+      benchmark::DoNotOptimize(c);
+      benchmark::ClobberMemory();
+    }
+  };
+  benchmark::RegisterBenchmark(operation_name, bench)->Range(8, 1 << 20);
+}
+
+template <bool Aligned, class Operation>
+static void bm_vector_bool(std::string operation_name, Operation copy) {
+  auto bench = [copy](auto& st) {
+    auto n = st.range();
+    std::vector<bool> in(n, true);
+    std::vector<bool> out(Aligned ? n : n + 8);
+    benchmark::DoNotOptimize(&in);
+    auto first = in.begin();
+    auto last  = in.end();
+    auto dst   = Aligned ? out.begin() : out.begin() + 4;
+    for ([[maybe_unused]] auto _ : st) {
+      auto result = copy(first, last, dst);
+      benchmark::DoNotOptimize(result);
+      benchmark::DoNotOptimize(out);
+      benchmark::ClobberMemory();
+    }
+  };
+  benchmark::RegisterBenchmark(operation_name, bench)->Range(64, 1 << 20);
+}
+
+int main(int argc, char** argv) {
+  auto std_copy    = [](auto first, auto last, auto out) { return std::copy(first, last, out); };
+  auto ranges_copy = [](auto first, auto last, auto out) { return std::ranges::copy(first, last, out); };
+
+  // std::copy
+  bm_general<std::vector<int>>("std::copy(vector<int>)", std_copy);
+  bm_general<std::deque<int>>("std::copy(deque<int>)", std_copy);
+  bm_general<std::list<int>>("std::copy(list<int>)", std_copy);
+  bm_vector_bool<true>("std::copy(vector<bool>) (aligned)", std_copy);
+  bm_vector_bool<false>("std::copy(vector<bool>) (unaligned)", std_copy);
+
+  // ranges::copy
+  bm_general<std::vector<int>>("ranges::copy(vector<int>)", ranges_copy);
+  bm_general<std::deque<int>>("ranges::copy(deque<int>)", ranges_copy);
+  bm_general<std::list<int>>("ranges::copy(list<int>)", ranges_copy);
+  bm_vector_bool<true>("ranges::copy(vector<bool>) (aligned)", ranges_copy);
+  bm_vector_bool<false>("ranges::copy(vector<bool>) (unaligned)", ranges_copy);
+
+  benchmark::Initialize(&argc, argv);
+  benchmark::RunSpecifiedBenchmarks();
+  benchmark::Shutdown();
+  return 0;
+}
diff --git a/libcxx/test/benchmarks/algorithms/modifying/copy_backward.bench.cpp b/libcxx/test/benchmarks/algorithms/modifying/copy_backward.bench.cpp
new file mode 100644
index 0000000000000..6f9360533db28
--- /dev/null
+++ b/libcxx/test/benchmarks/algorithms/modifying/copy_backward.bench.cpp
@@ -0,0 +1,86 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++11, c++14, c++17
+
+#include <algorithm>
+#include <deque>
+#include <iterator>
+#include <list>
+#include <string>
+#include <vector>
+
+#include "benchmark/benchmark.h"
+#include "../../GenerateInput.h"
+
+template <class Container, class Operation>
+void bm_general(std::string operation_name, Operation copy_backward) {
+  auto bench = [copy_backward](auto& st) {
+    auto const size = st.range(0);
+    using ValueType = typename Container::value_type;
+    Container c;
+    std::generate_n(std::back_inserter(c), size, [] { return Generate<ValueType>::random(); });
+
+    std::vector<ValueType> out(size);
+
+    for ([[maybe_unused]] auto _ : st) {
+      auto result = copy_backward(c.begin(), c.end(), out.end());
+      benchmark::DoNotOptimize(result);
+      benchmark::DoNotOptimize(out);
+      benchmark::DoNotOptimize(c);
+      benchmark::ClobberMemory();
+    }
+  };
+  benchmark::RegisterBenchmark(operation_name, bench)->Range(8, 1 << 20);
+}
+
+template <bool Aligned, class Operation>
+static void bm_vector_bool(std::string operation_name, Operation copy_backward) {
+  auto bench = [copy_backward](auto& st) {
+    auto n = st.range();
+    std::vector<bool> in(n, true);
+    std::vector<bool> out(Aligned ? n : n + 8);
+    benchmark::DoNotOptimize(&in);
+    auto first = in.begin();
+    auto last  = in.end();
+    auto dst   = Aligned ? out.end() : out.end() - 4;
+    for ([[maybe_unused]] auto _ : st) {
+      auto result = copy_backward(first, last, dst);
+      benchmark::DoNotOptimize(result);
+      benchmark::DoNotOptimize(out);
+      benchmark::ClobberMemory();
+    }
+  };
+  benchmark::RegisterBenchmark(operation_name, bench)->Range(64, 1 << 20);
+}
+
+int main(int argc, char** argv) {
+  auto std_copy_backward    = [](auto first, auto last, auto out) { return std::copy_backward(first, last, out); };
+  auto ranges_copy_backward = [](auto first, auto last, auto out) {
+    return std::ranges::copy_backward(first, last, out);
+  };
+
+  // std::copy
+  bm_general<std::vector<int>>("std::copy_backward(vector<int>)", std_copy_backward);
+  bm_general<std::deque<int>>("std::copy_backward(deque<int>)", std_copy_backward);
+  bm_general<std::list<int>>("std::copy_backward(list<int>)", std_copy_backward);
+  bm_vector_bool<true>("std::copy_backward(vector<bool>) (aligned)", std_copy_backward);
+  bm_vector_bool<false>("std::copy_backward(vector<bool>) (unaligned)", std_copy_backward);
+
+  // ranges::copy
+  bm_general<std::vector<int>>("ranges::copy_backward(vector<int>)", ranges_copy_backward);
+  bm_general<std::deque<int>>("ranges::copy_backward(deque<int>)", ranges_copy_backward);
+  bm_general<std::list<int>>("ranges::copy_backward(list<int>)", ranges_copy_backward);
+  bm_vector_bool<true>("ranges::copy_backward(vector<bool>) (aligned)", ranges_copy_backward);
+  bm_vector_bool<false>("ranges::copy_backward(vector<bool>) (unaligned)", ranges_copy_backward);
+
+  benchmark::Initialize(&argc, argv);
+  benchmark::RunSpecifiedBenchmarks();
+  benchmark::Shutdown();
+  return 0;
+}
diff --git a/libcxx/test/benchmarks/algorithms/modifying/copy_if.bench.cpp b/libcxx/test/benchmarks/algorithms/modifying/copy_if.bench.cpp
new file mode 100644
index 0000000000000..8a298c703e4e8
--- /dev/null
+++ b/libcxx/test/benchmarks/algorithms/modifying/copy_if.bench.cpp
@@ -0,0 +1,105 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++11, c++14, c++17
+
+#include <algorithm>
+#include <deque>
+#include <iterator>
+#include <list>
+#include <string>
+#include <vector>
+
+#include "benchmark/benchmark.h"
+#include "../../GenerateInput.h"
+
+// Benchmark copying one out of two element, in alternance. This is basically
+// the worst case for this algorithm, I don't think there are many optimizations
+// that can be applied in this case.
+template <class Container, class Operation>
+void bm_copy_every_other_element(std::string operation_name, Operation copy_if) {
+  auto bench = [copy_if](auto& st) {
+    auto const size = st.range(0);
+    using ValueType = typename Container::value_type;
+    Container c;
+    std::generate_n(std::back_inserter(c), size, [] { return Generate<ValueType>::random(); });
+
+    std::vector<ValueType> out(size);
+
+    for ([[maybe_unused]] auto _ : st) {
+      bool do_copy = false;
+      auto pred    = [&do_copy](auto& element) {
+        benchmark::DoNotOptimize(element);
+        do_copy = !do_copy;
+        return do_copy;
+      };
+      auto result = copy_if(c.begin(), c.end(), out.begin(), pred);
+      benchmark::DoNotOptimize(result);
+      benchmark::DoNotOptimize(out);
+      benchmark::DoNotOptimize(c);
+      benchmark::ClobberMemory();
+    }
+  };
+  benchmark::RegisterBenchmark(operation_name, bench)->Range(8, 1 << 20);
+}
+
+// Copy the full range.
+template <class Container, class Operation>
+void bm_copy_entire_range(std::string operation_name, Operation copy_if) {
+  auto bench = [copy_if](auto& st) {
+    auto const size = st.range(0);
+    using ValueType = typename Container::value_type;
+    Container c;
+    std::generate_n(std::back_inserter(c), size, [] { return Generate<ValueType>::random(); });
+
+    std::vector<ValueType> out(size);
+
+    for ([[maybe_unused]] auto _ : st) {
+      auto pred = [](auto& element) {
+        benchmark::DoNotOptimize(element);
+        return true;
+      };
+      auto result = copy_if(c.begin(), c.end(), out.begin(), pred);
+      benchmark::DoNotOptimize(result);
+      benchmark::DoNotOptimize(out);
+      benchmark::DoNotOptimize(c);
+      benchmark::ClobberMemory();
+    }
+  };
+  benchmark::RegisterBenchmark(operation_name, bench)->Range(8, 1 << 20);
+}
+
+int main(int argc, char** argv) {
+  auto std_copy_if    = [](auto first, auto last, auto out, auto pred) { return std::copy_if(first, last, out, pred); };
+  auto ranges_copy_if = [](auto first, auto last, auto out, auto pred) {
+    return std::ranges::copy_if(first, last, out, pred);
+  };
+
+  // std::copy_if
+  bm_copy_every_other_element<std::vector<int>>("std::copy_if(vector<int>) (every other)", std_copy_if);
+  bm_copy_every_other_element<std::deque<int>>("std::copy_if(deque<int>) (every other)", std_copy_if);
+  bm_copy_every_other_element<std::list<int>>("std::copy_if(list<int>) (every other)", std_copy_if);
+
+  bm_copy_entire_range<std::vector<int>>("std::copy_if(vector<int>) (entire range)", std_copy_if);
+  bm_copy_entire_range<std::deque<int>>("std::copy_if(deque<int>) (entire range)", std_copy_if);
+  bm_copy_entire_range<std::list<int>>("std::copy_if(list<int>) (entire range)", std_copy_if);
+
+  // ranges::copy
+  bm_copy_every_other_element<std::vector<int>>("ranges::copy_if(vector<int>) (every other)", ranges_copy_if);
+  bm_copy_every_other_element<std::deque<int>>("ranges::copy_if(deque<int>) (every other)", ranges_copy_if);
+  bm_copy_every_other_element<std::list<int>>("ranges::copy_if(list<int>) (every other)", ranges_copy_if);
+
+  bm_copy_entire_range<std::vector<int>>("ranges::copy_if(vector<int>) (entire range)", ranges_copy_if);
+  bm_copy_entire_range<std::deque<int>>("ranges::copy_if(deque<int>) (entire range)", ranges_copy_if);
+  bm_copy_entire_range<std::list<int>>("ranges::copy_if(list<int>) (entire range)", ranges_copy_if);
+
+  benchmark::Initialize(&argc, argv);
+  benchmark::RunSpecifiedBenchmarks();
+  benchmark::Shutdown();
+  return 0;
+}
diff --git a/libcxx/test/benchmarks/algorithms/modifying/copy_n.bench.cpp b/libcxx/test/benchmarks/algorithms/modifying/copy_n.bench.cpp
new file mode 100644
index 0000000000000..f4eb98f91df1c
--- /dev/null
+++ b/libcxx/test/benchmarks/algorithms/modifying/copy_n.bench.cpp
@@ -0,0 +1,83 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++11, c++14, c++17
+
+#include <algorithm>
+#include <deque>
+#include <iterator>
+#include <list>
+#include <string>
+#include <vector>
+
+#include "benchmark/benchmark.h"
+#include "../../GenerateInput.h"
+
+template <class Container, class Operation>
+void bm_general(std::string operation_name, Operation copy_n) {
+  auto bench = [copy_n](auto& st) {
+    auto const size = st.range(0);
+    using ValueType = typename Container::value_type;
+    Container c;
+    std::generate_n(std::back_inserter(c), size, [] { return Generate<ValueType>::random(); });
+
+    std::vector<ValueType> out(size);
+
+    for ([[maybe_unused]] auto _ : st) {
+      auto result = copy_n(c.begin(), size, out.begin());
+      benchmark::DoNotOptimize(result);
+      benchmark::DoNotOptimize(out);
+      benchmark::DoNotOptimize(c);
+      benchmark::ClobberMemory();
+    }
+  };
+  benchmark::RegisterBenchmark(operation_name, bench)->Range(8, 1 << 20);
+}
+
+template <bool Aligned, class Operation>
+static void bm_vector_bool(std::string operation_name, Operation copy_n) {
+  auto bench = [copy_n](auto& st) {
+    auto n = st.range();
+    std::vector<bool> in(n, true);
+    std::vector<bool> out(Aligned ? n : n + 8);
+    benchmark::DoNotOptimize(&in);
+    auto first = in.begin();
+    auto dst   = Aligned ? out.begin() : out.begin() + 4;
+    for ([[maybe_unused]] auto _ : st) {
+      auto result = copy_n(first, n, dst);
+      benchmark::DoNotOptimize(resul...
[truncated]

@ldionne ldionne force-pushed the review/benchmark-add-copy branch from 8df7cad to bf61250 Compare February 19, 2025 18:46
@ldionne ldionne added the pending-ci Merging the PR is only pending completion of CI label Feb 19, 2025
@ldionne ldionne merged commit 8feb5ba into llvm:main Feb 20, 2025
80 checks passed
@ldionne ldionne deleted the review/benchmark-add-copy branch February 20, 2025 13:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. pending-ci Merging the PR is only pending completion of CI
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants