[flang][runtime] Make defined formatted I/O process format elementally (#74150)
[llvm-project.git] / libcxx / benchmarks / allocation.bench.cpp
blob1d0c71f5bec19eadc35f035475406977f3b4806e
1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "benchmark/benchmark.h"
11 #include <cassert>
12 #include <new>
13 #include <vector>
15 struct PointerList {
16 PointerList* Next = nullptr;
19 struct MallocWrapper {
20 __attribute__((always_inline)) static void* Allocate(size_t N) { return std::malloc(N); }
21 __attribute__((always_inline)) static void Deallocate(void* P, size_t) { std::free(P); }
24 struct NewWrapper {
25 __attribute__((always_inline)) static void* Allocate(size_t N) { return ::operator new(N); }
26 __attribute__((always_inline)) static void Deallocate(void* P, size_t) { ::operator delete(P); }
29 struct BuiltinNewWrapper {
30 __attribute__((always_inline)) static void* Allocate(size_t N) { return __builtin_operator_new(N); }
31 __attribute__((always_inline)) static void Deallocate(void* P, size_t) { __builtin_operator_delete(P); }
34 struct BuiltinSizedNewWrapper {
35 __attribute__((always_inline)) static void* Allocate(size_t N) { return __builtin_operator_new(N); }
36 __attribute__((always_inline)) static void Deallocate(void* P, size_t N) { __builtin_operator_delete(P, N); }
39 template <class AllocWrapper>
40 static void BM_AllocateAndDeallocate(benchmark::State& st) {
41 const size_t alloc_size = st.range(0);
42 while (st.KeepRunning()) {
43 void* p = AllocWrapper::Allocate(alloc_size);
44 benchmark::DoNotOptimize(p);
45 AllocWrapper::Deallocate(p, alloc_size);
49 template <class AllocWrapper>
50 static void BM_AllocateOnly(benchmark::State& st) {
51 const size_t alloc_size = st.range(0);
52 PointerList* Start = nullptr;
54 while (st.KeepRunning()) {
55 PointerList* p = (PointerList*)AllocWrapper::Allocate(alloc_size);
56 benchmark::DoNotOptimize(p);
57 p->Next = Start;
58 Start = p;
61 PointerList* Next = Start;
62 while (Next) {
63 PointerList* Tmp = Next;
64 Next = Tmp->Next;
65 AllocWrapper::Deallocate(Tmp, alloc_size);
69 template <class AllocWrapper>
70 static void BM_DeallocateOnly(benchmark::State& st) {
71 const size_t alloc_size = st.range(0);
72 const auto NumAllocs = st.max_iterations;
74 std::vector<void*> Pointers(NumAllocs);
75 for (auto& p : Pointers) {
76 p = AllocWrapper::Allocate(alloc_size);
79 void** Data = Pointers.data();
80 [[maybe_unused]] void** const End = Pointers.data() + Pointers.size();
81 while (st.KeepRunning()) {
82 AllocWrapper::Deallocate(*Data, alloc_size);
83 Data += 1;
85 assert(Data == End);
88 static int RegisterAllocBenchmarks() {
89 using FnType = void (*)(benchmark::State&);
90 struct {
91 const char* name;
92 FnType func;
93 } TestCases[] = {
94 {"BM_Malloc", &BM_AllocateAndDeallocate<MallocWrapper>},
95 {"BM_New", &BM_AllocateAndDeallocate<NewWrapper>},
96 {"BM_BuiltinNewDelete", BM_AllocateAndDeallocate<BuiltinNewWrapper>},
97 {"BM_BuiltinSizedNewDelete", BM_AllocateAndDeallocate<BuiltinSizedNewWrapper>},
98 {"BM_BuiltinNewAllocateOnly", BM_AllocateOnly<BuiltinSizedNewWrapper>},
99 {"BM_BuiltinNewSizedDeallocateOnly", BM_DeallocateOnly<BuiltinSizedNewWrapper>},
102 for (auto TC : TestCases) {
103 benchmark::RegisterBenchmark(TC.name, TC.func)->Range(16, 4096 * 2);
105 return 0;
107 int Sink = RegisterAllocBenchmarks();
109 BENCHMARK_MAIN();