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 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> 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