diff --git a/packages/feedsim/install_feedsim.sh b/packages/feedsim/install_feedsim.sh index 03c22fe44..8d69d901d 100755 --- a/packages/feedsim/install_feedsim.sh +++ b/packages/feedsim/install_feedsim.sh @@ -107,6 +107,22 @@ rsync -a --exclude=src \ "${FEEDSIM_THIRD_PARTY_SRC}/" cd "${FEEDSIM_THIRD_PARTY_SRC}" +# Optionally build DynamoRIO for tracing support. +DR_TRACE_FLAGS=() +if [ "${ENABLE_DR_TRACE:-0}" = "1" ]; then + msg "[DR_TRACE] Setting up DynamoRIO tracing support..." + BUILD_DIR="${FEEDSIM_THIRD_PARTY_SRC}" + export BUILD_DIR + # shellcheck disable=SC1091 + source "${BENCHPRESS_ROOT}/packages/common/dr_trace/install_dynamorio.sh" + DR_TRACE_FLAGS=( + -DENABLE_DR_TRACE=ON + -DDR_INSTALL="${DR_INSTALL}" + -DDR_TRACE_DIR="${BENCHPRESS_ROOT}/packages/common/dr_trace" + ) + msg "[DR_TRACE] DR_INSTALL=${DR_INSTALL}" +fi + # Installing cmake-4.0.3 if ! [ -d "cmake-4.0.3" ]; then @@ -380,6 +396,7 @@ cmake -G Ninja \ -DFEEDSIM_USE_DLRM=ON \ -DTorch_DIR="${FEEDSIM_THIRD_PARTY_SRC}/libtorch/share/cmake/Torch" \ -DCMAKE_PREFIX_PATH="${FEEDSIM_THIRD_PARTY_SRC}/libtorch" \ + "${DR_TRACE_FLAGS[@]}" \ ../ # Dependencies (fmt, folly, fbthrift, etc.) are already installed above via diff --git a/packages/feedsim/install_feedsim_aarch64.sh b/packages/feedsim/install_feedsim_aarch64.sh index 4d797ba47..9929b6925 100755 --- a/packages/feedsim/install_feedsim_aarch64.sh +++ b/packages/feedsim/install_feedsim_aarch64.sh @@ -90,6 +90,22 @@ cp -f "${BENCHPRESS_ROOT}/packages/feedsim/third_party/src/third_party/CMakeList "${FEEDSIM_ROOT_SRC}/src/third_party/CMakeLists.txt" cd "${FEEDSIM_THIRD_PARTY_SRC}" +# Optionally build DynamoRIO for tracing support. +DR_TRACE_FLAGS=() +if [ "${ENABLE_DR_TRACE:-0}" = "1" ]; then + msg "[DR_TRACE] Setting up DynamoRIO tracing support..." + BUILD_DIR="${FEEDSIM_THIRD_PARTY_SRC}" + export BUILD_DIR + # shellcheck disable=SC1091 + source "${BENCHPRESS_ROOT}/packages/common/dr_trace/install_dynamorio.sh" + DR_TRACE_FLAGS=( + -DENABLE_DR_TRACE=ON + -DDR_INSTALL="${DR_INSTALL}" + -DDR_TRACE_DIR="${BENCHPRESS_ROOT}/packages/common/dr_trace" + ) + msg "[DR_TRACE] DR_INSTALL=${DR_INSTALL}" +fi + DEP_CMAKE_VERSION="4.0.3" # Installing cmake if ! [ -d "cmake-${DEP_CMAKE_VERSION}-linux-aarch64" ]; then @@ -415,6 +431,7 @@ cmake -G Ninja \ -DCMAKE_EXE_LINKER_FLAGS_RELEASE="$FS_LDFLAGS" \ -DFEEDSIM_USE_DLRM=ON \ -DTorch_DIR="${FEEDSIM_THIRD_PARTY_SRC}/libtorch/share/cmake/Torch" \ + "${DR_TRACE_FLAGS[@]}" \ ../ # Third-party deps (fmt, folly, fizz, wangle, mvfst, fbthrift) are built by this diff --git a/packages/feedsim/third_party/src/workloads/ranking/CMakeLists.txt b/packages/feedsim/third_party/src/workloads/ranking/CMakeLists.txt index 0504d6d41..fb746afe9 100644 --- a/packages/feedsim/third_party/src/workloads/ranking/CMakeLists.txt +++ b/packages/feedsim/third_party/src/workloads/ranking/CMakeLists.txt @@ -404,6 +404,27 @@ if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") target_link_options(LeafNodeRank PRIVATE -Wl,--no-relax) endif() +# DynamoRIO tracing support +option(ENABLE_DR_TRACE "Enable DynamoRIO tracing hooks" OFF) +if(ENABLE_DR_TRACE) + if(NOT DR_TRACE_DIR) + message(FATAL_ERROR "ENABLE_DR_TRACE=ON requires -DDR_TRACE_DIR=") + endif() + add_subdirectory(${DR_TRACE_DIR} ${CMAKE_BINARY_DIR}/dr_trace) + target_link_libraries(LeafNodeRank PRIVATE dr_trace) + if(NOT CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") + # Without this the linker emits one RWE PT_LOAD, DR records LeafNodeRank + # as a single 465MB module, and raw2trace segfaults decoding the gap + # between segments. Scoped to the traced build so the default binary is + # unchanged. + target_link_options(LeafNodeRank PRIVATE -Wl,-z,separate-code) + endif() + # drsyms stubs must be compiled into the binary rather than libdr_trace.a so + # they resolve references from --whole-archive drmemtrace_drstatic before the + # linker finishes. + target_sources(LeafNodeRank PRIVATE ${DR_TRACE_DIR}/drsyms_stubs.c) +endif() + # Re-link libraries at the end to resolve circular static library dependencies # (folly/glog use gflags DEFINE_* macros, fbthrift has internal cross-lib refs) target_link_libraries(LeafNodeRank PRIVATE diff --git a/packages/feedsim/third_party/src/workloads/ranking/LeafNodeRank.cc b/packages/feedsim/third_party/src/workloads/ranking/LeafNodeRank.cc index 4c8cc46bc..d78c2ef85 100644 --- a/packages/feedsim/third_party/src/workloads/ranking/LeafNodeRank.cc +++ b/packages/feedsim/third_party/src/workloads/ranking/LeafNodeRank.cc @@ -73,6 +73,42 @@ #include "dwarfs/dlrm.h" #endif +#ifdef DR_TRACE_INCLUDED +#include +#include +#include "dr_trace.h" +static constexpr uint32_t kDrTraceDelaySeconds = 15; +static constexpr uint32_t kDrTraceDurationSeconds = 10; + +static constexpr int kFeedsimBasePort = 21212; + +static bool dr_trace_enabled_for_port(int port) { + const char* only_port = std::getenv("DR_TRACE_PORT"); + if (only_port != nullptr) { + return std::strcmp(only_port, "all") == 0 || std::atoi(only_port) == port; + } + return std::getenv("IS_AUTOSCALE_RUN") == nullptr || port == kFeedsimBasePort; +} + +// Force -raw_compress none for LeafNodeRank only. +static void dr_trace_disable_raw_compression() { + if (std::getenv("DYNAMORIO_OPTIONS") != nullptr) { + return; + } + const DrTraceConfig defaults; + const char* outdir = std::getenv("DR_TRACE_OUTDIR"); + const char* verbose = std::getenv("DR_TRACE_VERBOSE"); + const std::string opts = std::string( + "-rstats_to_stderr -no_hook_vsyscall" + " -disable_traces -no_enable_reset" + " -client_lib ';;-offline -raw_compress none" + " -verbose ") + + (verbose != nullptr ? verbose : std::to_string(defaults.verbose)) + + " -outdir " + (outdir != nullptr ? outdir : defaults.outdir) + "'"; + setenv("DYNAMORIO_OPTIONS", opts.c_str(), 1); +} +#endif + #include "if/gen-cpp2/ranking_types.h" #include "../search/ICacheBuster.h" @@ -2958,6 +2994,16 @@ int main(int argc, char** argv) { }); debug_dump_thread.detach(); +#ifdef DR_TRACE_INCLUDED + if (dr_trace_enabled_for_port(args.port_arg)) { + dr_trace_disable_raw_compression(); + trace_configure_env(); + std::thread( + trace_execution_delay) + .detach(); + } +#endif + server.run(); // One last dump after the server returns so the final state hits the