forked from OSchip/llvm-project
scudo: Add a basic malloc/free benchmark.
Differential Revision: https://reviews.llvm.org/D71104
This commit is contained in:
parent
bab9849963
commit
29f0a65671
|
@ -133,6 +133,7 @@ if(COMPILER_RT_HAS_SCUDO_STANDALONE)
|
||||||
CFLAGS ${SCUDO_CFLAGS}
|
CFLAGS ${SCUDO_CFLAGS}
|
||||||
PARENT_TARGET scudo_standalone)
|
PARENT_TARGET scudo_standalone)
|
||||||
|
|
||||||
|
add_subdirectory(benchmarks)
|
||||||
if(COMPILER_RT_INCLUDE_TESTS)
|
if(COMPILER_RT_INCLUDE_TESTS)
|
||||||
add_subdirectory(tests)
|
add_subdirectory(tests)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -64,6 +64,7 @@ struct AndroidSvelteConfig {
|
||||||
using TSDRegistryT = TSDRegistrySharedT<A, 1U>; // Shared, only 1 TSD.
|
using TSDRegistryT = TSDRegistrySharedT<A, 1U>; // Shared, only 1 TSD.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if SCUDO_CAN_USE_PRIMARY64
|
||||||
struct FuchsiaConfig {
|
struct FuchsiaConfig {
|
||||||
// 1GB Regions
|
// 1GB Regions
|
||||||
typedef SizeClassAllocator64<DefaultSizeClassMap, 30U> Primary;
|
typedef SizeClassAllocator64<DefaultSizeClassMap, 30U> Primary;
|
||||||
|
@ -71,6 +72,7 @@ struct FuchsiaConfig {
|
||||||
template <class A>
|
template <class A>
|
||||||
using TSDRegistryT = TSDRegistrySharedT<A, 8U>; // Shared, max 8 TSDs.
|
using TSDRegistryT = TSDRegistrySharedT<A, 8U>; // Shared, max 8 TSDs.
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
#if SCUDO_ANDROID
|
#if SCUDO_ANDROID
|
||||||
typedef AndroidConfig Config;
|
typedef AndroidConfig Config;
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
# To build these benchmarks, build the target "ScudoBenchmarks.$ARCH", where
|
||||||
|
# $ARCH is the name of the target architecture. For example,
|
||||||
|
# ScudoBenchmarks.x86_64 for 64-bit x86. The benchmark executable is then
|
||||||
|
# available under projects/compiler-rt/lib/scudo/standalone/benchmarks/ in the
|
||||||
|
# build directory.
|
||||||
|
|
||||||
|
include(AddLLVM)
|
||||||
|
|
||||||
|
set(SCUDO_BENCHMARK_CFLAGS -I${COMPILER_RT_SOURCE_DIR}/lib/scudo/standalone)
|
||||||
|
if(ANDROID)
|
||||||
|
list(APPEND SCUDO_BENCHMARK_CFLAGS -fno-emulated-tls)
|
||||||
|
endif()
|
||||||
|
string(REPLACE ";" " " SCUDO_BENCHMARK_CFLAGS " ${SCUDO_BENCHMARK_CFLAGS}")
|
||||||
|
|
||||||
|
foreach(arch ${SCUDO_STANDALONE_SUPPORTED_ARCH})
|
||||||
|
add_benchmark(ScudoBenchmarks.${arch}
|
||||||
|
malloc_benchmark.cpp
|
||||||
|
$<TARGET_OBJECTS:RTScudoStandalone.${arch}>)
|
||||||
|
set_property(TARGET ScudoBenchmarks.${arch} APPEND_STRING PROPERTY
|
||||||
|
COMPILE_FLAGS "${SCUDO_BENCHMARK_CFLAGS}")
|
||||||
|
endforeach()
|
|
@ -0,0 +1,101 @@
|
||||||
|
//===-- malloc_benchmark.cpp ------------------------------------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "allocator_config.h"
|
||||||
|
#include "combined.h"
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#include "benchmark/benchmark.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
template <typename Config> static void BM_malloc_free(benchmark::State &State) {
|
||||||
|
using AllocatorT = scudo::Allocator<Config>;
|
||||||
|
auto Deleter = [](AllocatorT *A) {
|
||||||
|
A->unmapTestOnly();
|
||||||
|
delete A;
|
||||||
|
};
|
||||||
|
std::unique_ptr<AllocatorT, decltype(Deleter)> Allocator(new AllocatorT,
|
||||||
|
Deleter);
|
||||||
|
Allocator->reset();
|
||||||
|
|
||||||
|
const size_t NBytes = State.range(0);
|
||||||
|
size_t PageSize = scudo::getPageSizeCached();
|
||||||
|
|
||||||
|
for (auto _ : State) {
|
||||||
|
void *Ptr = Allocator->allocate(NBytes, scudo::Chunk::Origin::Malloc);
|
||||||
|
auto *Data = reinterpret_cast<uint8_t *>(Ptr);
|
||||||
|
for (size_t I = 0; I < NBytes; I += PageSize)
|
||||||
|
Data[I] = 1;
|
||||||
|
benchmark::DoNotOptimize(Ptr);
|
||||||
|
Allocator->deallocate(Ptr, scudo::Chunk::Origin::Malloc);
|
||||||
|
}
|
||||||
|
|
||||||
|
State.SetBytesProcessed(uint64_t(State.iterations()) * uint64_t(NBytes));
|
||||||
|
}
|
||||||
|
|
||||||
|
static const size_t MinSize = 8;
|
||||||
|
static const size_t MaxSize = 128 * 1024;
|
||||||
|
|
||||||
|
// FIXME: Add DefaultConfig here once we can tear down the exclusive TSD
|
||||||
|
// cleanly.
|
||||||
|
BENCHMARK_TEMPLATE(BM_malloc_free, scudo::AndroidConfig)
|
||||||
|
->Range(MinSize, MaxSize);
|
||||||
|
BENCHMARK_TEMPLATE(BM_malloc_free, scudo::AndroidSvelteConfig)
|
||||||
|
->Range(MinSize, MaxSize);
|
||||||
|
#if SCUDO_CAN_USE_PRIMARY64
|
||||||
|
BENCHMARK_TEMPLATE(BM_malloc_free, scudo::FuchsiaConfig)
|
||||||
|
->Range(MinSize, MaxSize);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <typename Config>
|
||||||
|
static void BM_malloc_free_loop(benchmark::State &State) {
|
||||||
|
using AllocatorT = scudo::Allocator<Config>;
|
||||||
|
auto Deleter = [](AllocatorT *A) {
|
||||||
|
A->unmapTestOnly();
|
||||||
|
delete A;
|
||||||
|
};
|
||||||
|
std::unique_ptr<AllocatorT, decltype(Deleter)> Allocator(new AllocatorT,
|
||||||
|
Deleter);
|
||||||
|
Allocator->reset();
|
||||||
|
|
||||||
|
const size_t NumIters = State.range(0);
|
||||||
|
size_t PageSize = scudo::getPageSizeCached();
|
||||||
|
void *Ptrs[NumIters];
|
||||||
|
|
||||||
|
for (auto _ : State) {
|
||||||
|
for (void *&Ptr : Ptrs) {
|
||||||
|
Ptr = Allocator->allocate(8192, scudo::Chunk::Origin::Malloc);
|
||||||
|
auto *Data = reinterpret_cast<uint8_t *>(Ptr);
|
||||||
|
for (size_t I = 0; I < 8192; I += PageSize)
|
||||||
|
Data[I] = 1;
|
||||||
|
benchmark::DoNotOptimize(Ptr);
|
||||||
|
}
|
||||||
|
for (void *&Ptr : Ptrs)
|
||||||
|
Allocator->deallocate(Ptr, scudo::Chunk::Origin::Malloc);
|
||||||
|
}
|
||||||
|
|
||||||
|
State.SetBytesProcessed(uint64_t(State.iterations()) * uint64_t(NumIters) *
|
||||||
|
8192);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const size_t MinIters = 8;
|
||||||
|
static const size_t MaxIters = 32 * 1024;
|
||||||
|
|
||||||
|
// FIXME: Add DefaultConfig here once we can tear down the exclusive TSD
|
||||||
|
// cleanly.
|
||||||
|
BENCHMARK_TEMPLATE(BM_malloc_free_loop, scudo::AndroidConfig)
|
||||||
|
->Range(MinIters, MaxIters);
|
||||||
|
BENCHMARK_TEMPLATE(BM_malloc_free_loop, scudo::AndroidSvelteConfig)
|
||||||
|
->Range(MinIters, MaxIters);
|
||||||
|
#if SCUDO_CAN_USE_PRIMARY64
|
||||||
|
BENCHMARK_TEMPLATE(BM_malloc_free_loop, scudo::FuchsiaConfig)
|
||||||
|
->Range(MinIters, MaxIters);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
BENCHMARK_MAIN();
|
|
@ -51,6 +51,7 @@ template <class Allocator, u32 MaxTSDCount> struct TSDRegistrySharedT {
|
||||||
unmap(reinterpret_cast<void *>(TSDs),
|
unmap(reinterpret_cast<void *>(TSDs),
|
||||||
sizeof(TSD<Allocator>) * NumberOfTSDs);
|
sizeof(TSD<Allocator>) * NumberOfTSDs);
|
||||||
setCurrentTSD(nullptr);
|
setCurrentTSD(nullptr);
|
||||||
|
pthread_key_delete(PThreadKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
ALWAYS_INLINE void initThreadMaybe(Allocator *Instance,
|
ALWAYS_INLINE void initThreadMaybe(Allocator *Instance,
|
||||||
|
|
|
@ -15,6 +15,7 @@ group("scudo") {
|
||||||
deps = []
|
deps = []
|
||||||
foreach(toolchain, supported_toolchains) {
|
foreach(toolchain, supported_toolchains) {
|
||||||
deps += [
|
deps += [
|
||||||
|
"standalone/benchmarks:ScudoBenchmarks($toolchain)",
|
||||||
"standalone/tests:ScudoCUnitTest($toolchain)",
|
"standalone/tests:ScudoCUnitTest($toolchain)",
|
||||||
"standalone/tests:ScudoCxxUnitTest($toolchain)",
|
"standalone/tests:ScudoCxxUnitTest($toolchain)",
|
||||||
"standalone/tests:ScudoUnitTest($toolchain)",
|
"standalone/tests:ScudoUnitTest($toolchain)",
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
executable("ScudoBenchmarks") {
|
||||||
|
configs += [ "//llvm/utils/gn/build:crt_code" ]
|
||||||
|
sources = [
|
||||||
|
"malloc_benchmark.cpp",
|
||||||
|
]
|
||||||
|
deps = [
|
||||||
|
"//compiler-rt/lib/scudo/standalone:sources",
|
||||||
|
"//llvm/utils/benchmark",
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
static_library("benchmark") {
|
||||||
|
sources = [
|
||||||
|
"src/benchmark.cc",
|
||||||
|
"src/benchmark_register.cc",
|
||||||
|
"src/colorprint.cc",
|
||||||
|
"src/commandlineflags.cc",
|
||||||
|
"src/complexity.cc",
|
||||||
|
"src/console_reporter.cc",
|
||||||
|
"src/counter.cc",
|
||||||
|
"src/csv_reporter.cc",
|
||||||
|
"src/json_reporter.cc",
|
||||||
|
"src/reporter.cc",
|
||||||
|
"src/sleep.cc",
|
||||||
|
"src/statistics.cc",
|
||||||
|
"src/string_util.cc",
|
||||||
|
"src/sysinfo.cc",
|
||||||
|
"src/timers.cc",
|
||||||
|
]
|
||||||
|
deps = [ "//llvm/utils/gn/build/libs/pthread" ]
|
||||||
|
public_configs = [ ":benchmark_config" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
config("benchmark_config") {
|
||||||
|
include_dirs = [ "include" ]
|
||||||
|
}
|
Loading…
Reference in New Issue