1 //===----------------------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "benchmark/benchmark.h"
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
); }
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
);
61 PointerList
* Next
= Start
;
63 PointerList
* 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
);
88 static int RegisterAllocBenchmarks() {
89 using FnType
= void (*)(benchmark::State
&);
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);
107 int Sink
= RegisterAllocBenchmarks();