blob: 078b7eb6633e3071e395428ebaa8b0fe2c844fd0 [file] [log] [blame]
//===- shallow-call-bench.cc - XRay Profiling Mode Benchmarks -------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// These benchmarks measure the cost of XRay profiling mode when enabled.
//
//===----------------------------------------------------------------------===//
#include <atomic>
#include <iostream>
#include <mutex>
#include <thread>
#include "benchmark/benchmark.h"
#include "xray/xray_log_interface.h"
namespace {
std::atomic<int> some_global{0};
std::atomic<int> some_temporary{0};
[[clang::xray_never_instrument]] static void profiling_setup() {
if (__xray_log_select_mode("xray-profiling") != XRAY_REGISTRATION_OK) {
std::cerr << "Failed selecting 'xray-profiling' mode. Aborting.\n";
std::abort();
}
if (__xray_log_init_mode("xray-profiling", "no_flush=true") !=
XRAY_LOG_INITIALIZED) {
std::cerr << "Failed initializing xray-profiling mode. Aborting.\n";
std::abort();
};
__xray_patch();
}
[[clang::xray_never_instrument]] static void profiling_teardown() {
if (__xray_log_finalize() != XRAY_LOG_FINALIZED) {
std::cerr << "Failed to finalize xray-profiling mode. Aborting.\n";
std::abort();
}
if (__xray_log_flushLog() != XRAY_LOG_FLUSHED) {
std::cerr << "Failed to flush xray-profiling mode. Aborting.\n";
std::abort();
}
}
} // namespace
#define XRAY_WEAK_NOINLINE \
[[clang::xray_always_instrument]] __attribute__((weak)) \
__attribute__((noinline))
XRAY_WEAK_NOINLINE int shallow() {
return some_global.fetch_add(1, std::memory_order_acq_rel);
}
// This benchmark measures the cost of XRay instrumentation in shallow function
// call stack, where we instrument a single function call. We make the function
// a combination of: no-inline, have weak symbol binding, and force
// instrumentation with XRay. Each iteration of the benchmark will initialize
// the XRay profiling runtime, and then tear it down afterwards.
//
// We also run the benchmark on multiple threads, to track and identify
// whether/where the contention and scalability issues are in the implementation
// of the profiling runtime.
[[clang::xray_never_instrument]] static void BM_XRayProfilingShallowStack(
benchmark::State &state) {
if (state.thread_index == 0) profiling_setup();
benchmark::DoNotOptimize(some_temporary = shallow());
for (auto _ : state) benchmark::DoNotOptimize(some_temporary = shallow());
if (state.thread_index == 0) profiling_teardown();
}
BENCHMARK(BM_XRayProfilingShallowStack)->ThreadRange(1, 64)->UseRealTime();
BENCHMARK_MAIN();