1 //===-- malloc_benchmark.cpp ------------------------------------*- C++ -*-===//
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 //===----------------------------------------------------------------------===//
8
9 #include "allocator_config.h"
10 #include "combined.h"
11 #include "common.h"
12
13 #include "benchmark/benchmark.h"
14
15 #include <memory>
16
BM_malloc_free(benchmark::State & State)17 template <typename Config> static void BM_malloc_free(benchmark::State &State) {
18 using AllocatorT = scudo::Allocator<Config>;
19 auto Deleter = [](AllocatorT *A) {
20 A->unmapTestOnly();
21 delete A;
22 };
23 std::unique_ptr<AllocatorT, decltype(Deleter)> Allocator(new AllocatorT,
24 Deleter);
25 Allocator->reset();
26
27 const size_t NBytes = State.range(0);
28 size_t PageSize = scudo::getPageSizeCached();
29
30 for (auto _ : State) {
31 void *Ptr = Allocator->allocate(NBytes, scudo::Chunk::Origin::Malloc);
32 auto *Data = reinterpret_cast<uint8_t *>(Ptr);
33 for (size_t I = 0; I < NBytes; I += PageSize)
34 Data[I] = 1;
35 benchmark::DoNotOptimize(Ptr);
36 Allocator->deallocate(Ptr, scudo::Chunk::Origin::Malloc);
37 }
38
39 State.SetBytesProcessed(uint64_t(State.iterations()) * uint64_t(NBytes));
40 }
41
42 static const size_t MinSize = 8;
43 static const size_t MaxSize = 128 * 1024;
44
45 // FIXME: Add DefaultConfig here once we can tear down the exclusive TSD
46 // cleanly.
47 BENCHMARK_TEMPLATE(BM_malloc_free, scudo::AndroidConfig)
48 ->Range(MinSize, MaxSize);
49 BENCHMARK_TEMPLATE(BM_malloc_free, scudo::AndroidSvelteConfig)
50 ->Range(MinSize, MaxSize);
51 #if SCUDO_CAN_USE_PRIMARY64
52 BENCHMARK_TEMPLATE(BM_malloc_free, scudo::FuchsiaConfig)
53 ->Range(MinSize, MaxSize);
54 #endif
55
56 template <typename Config>
BM_malloc_free_loop(benchmark::State & State)57 static void BM_malloc_free_loop(benchmark::State &State) {
58 using AllocatorT = scudo::Allocator<Config>;
59 auto Deleter = [](AllocatorT *A) {
60 A->unmapTestOnly();
61 delete A;
62 };
63 std::unique_ptr<AllocatorT, decltype(Deleter)> Allocator(new AllocatorT,
64 Deleter);
65 Allocator->reset();
66
67 const size_t NumIters = State.range(0);
68 size_t PageSize = scudo::getPageSizeCached();
69 void *Ptrs[NumIters];
70
71 for (auto _ : State) {
72 size_t SizeLog2 = 0;
73 for (void *&Ptr : Ptrs) {
74 Ptr = Allocator->allocate(1 << SizeLog2, scudo::Chunk::Origin::Malloc);
75 auto *Data = reinterpret_cast<uint8_t *>(Ptr);
76 for (size_t I = 0; I < 1 << SizeLog2; I += PageSize)
77 Data[I] = 1;
78 benchmark::DoNotOptimize(Ptr);
79 SizeLog2 = (SizeLog2 + 1) % 16;
80 }
81 for (void *&Ptr : Ptrs)
82 Allocator->deallocate(Ptr, scudo::Chunk::Origin::Malloc);
83 }
84
85 State.SetBytesProcessed(uint64_t(State.iterations()) * uint64_t(NumIters) *
86 8192);
87 }
88
89 static const size_t MinIters = 8;
90 static const size_t MaxIters = 32 * 1024;
91
92 // FIXME: Add DefaultConfig here once we can tear down the exclusive TSD
93 // cleanly.
94 BENCHMARK_TEMPLATE(BM_malloc_free_loop, scudo::AndroidConfig)
95 ->Range(MinIters, MaxIters);
96 BENCHMARK_TEMPLATE(BM_malloc_free_loop, scudo::AndroidSvelteConfig)
97 ->Range(MinIters, MaxIters);
98 #if SCUDO_CAN_USE_PRIMARY64
99 BENCHMARK_TEMPLATE(BM_malloc_free_loop, scudo::FuchsiaConfig)
100 ->Range(MinIters, MaxIters);
101 #endif
102
103 BENCHMARK_MAIN();
104