| //===- fdrmode-bench.cc - XRay Instrumentation Benchmarks -----------------===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // Define benchmarks for measuring the cost of XRay instrumentation when using |
| // flight data recorder mode. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include <assert.h> |
| #include <fcntl.h> |
| #include <unistd.h> |
| #include "benchmark/benchmark.h" |
| #include "xray/xray_interface.h" |
| #include "xray/xray_log_interface.h" |
| |
| namespace { |
| |
| // This needs to be a global value so that the compiler doesn't end up writing |
| // to data on the stack. We also mark it volatile to preserve all the loads and |
| // stores performed on this variable. |
| volatile int val = 0; |
| |
| } // namespace |
| |
| // We define a multi-threaded benchmark which measures the overall costs |
| // introduced by the XRay handlers upstream. This will exercise a tight loop |
| // calling a single function that practically does nothing. |
| [[clang::xray_always_instrument]] __attribute__((noinline)) |
| __attribute__((weak)) int |
| EmptyFunction() { |
| return 0; |
| } |
| |
| volatile bool log_initialized = false; |
| |
| // Force installation of the FDR logging implementation upstream, with the |
| // caveat that we're writing the log out to /dev/null. |
| [[clang::xray_never_instrument]] void SetUpXRayFDRMultiThreaded( |
| benchmark::State& state) { |
| if (!log_initialized) { |
| if (__xray_log_select_mode("xray-fdr") != |
| XRayLogRegisterStatus::XRAY_REGISTRATION_OK) |
| std::abort(); |
| |
| std::string flags = "no_file_flush=true:buffer_size="; |
| flags += std::to_string(getpagesize()) + ":buffer_max="; |
| flags += std::to_string(1 << 16); |
| __xray_log_init_mode("xray-fdr", flags.c_str()); |
| __xray_remove_customevent_handler(); |
| __xray_patch(); |
| log_initialized = true; |
| } |
| } |
| |
| [[clang::xray_never_instrument]] void TearDownXRayFDRMultiThreaded( |
| benchmark::State& state) { |
| if (log_initialized) { |
| log_initialized = false; |
| __xray_log_finalize(); |
| __xray_log_flushLog(); |
| __xray_unpatch(); |
| } |
| } |
| |
| [[clang::xray_never_instrument]] static void BM_XRayFDRMultiThreaded( |
| benchmark::State& state) { |
| if (state.thread_index == 0) { |
| SetUpXRayFDRMultiThreaded(state); |
| } |
| for (auto _ : state) { |
| val = EmptyFunction(); |
| benchmark::DoNotOptimize(val); |
| } |
| if (state.thread_index == 0) { |
| TearDownXRayFDRMultiThreaded(state); |
| } |
| } |
| |
| BENCHMARK(BM_XRayFDRMultiThreaded)->ThreadRange(1, 32); // Number of threads |
| |
| BENCHMARK_MAIN(); |