• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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