Skip to content

Commit

Permalink
[#12763] DocDB: Adding PGO build types: prof_gen and prof_use.
Browse files Browse the repository at this point in the history
Summary:
Added build types for generating and using profile for profile guided optimizations with clang.
Added forced profile dumping to tserver with prof_gen build.

For performance comparison of `release+lto` vs `prof_use+lto`  the profile was collected with CassandraKeyValue app.
Then CassandraKeyValue, CassandraTransactionalKeyValue and CassandraUniqueSecondaryIndex were run 9 times each.
Comparing the average of 9 runs of the average of the first 30 read ops/sec.
Parameters for all apps: --num_unique_keys 1000000  --num_threads_read 128 --num_threads_write 4 --nouuid --num_writes 10000  --num_reads 10000000
```
        app                         | release   | prof_use  |  prof_use/release
                                    |  ops/sec  |   ops/sec |
CassandraKeyValue                   |  43348.1  |  45550.8  |       1.051
CassandraTransactionalKeyValue      |  28487.5  |  29574.7  |       1.038
CassandraUniqueSecondaryIndex       |  39259.1  |  42316.8  |       1.078
```

Test Plan: Run builds and yb-sample-apps

Reviewers: dfelsing, mbautin

Reviewed By: dfelsing, mbautin

Subscribers: dfelsing, mbautin, bogdan

Differential Revision: https://phabricator.dev.yugabyte.com/D18258
  • Loading branch information
NatashaSerebryanaya committed Jul 22, 2022
1 parent 25e488d commit 34cb791
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 9 deletions.
17 changes: 17 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,23 @@ if ("${YB_BUILD_TYPE}" MATCHES "^(asan|tsan)$")
endif()

set(BUILD_SHARED_LIBS ON)
if ("${YB_BUILD_TYPE}" STREQUAL "prof_gen")
ADD_CXX_FLAGS("-fprofile-instr-generate -DYB_PROFGEN")
endif ()

if ("${YB_BUILD_TYPE}" STREQUAL "prof_use")
if (NOT YB_PGO_DATA_PATH)
message (SEND_ERROR "Pgo data path is not set.")
endif()
ADD_CXX_FLAGS("-fprofile-instr-use=${YB_PGO_DATA_PATH}")
# Even with the fresh profile data we might get warnings like
# warning: Function control flow change detected (hash mismatch)
# [-Wbackend-plugin]
# Silencing it for now.
ADD_CXX_FLAGS("-Wno-backend-plugin")
ADD_CXX_FLAGS("-Wno-profile-instr-unprofiled")
ADD_CXX_FLAGS("-Wno-profile-instr-out-of-date")
endif ()

# Position independent code is only necessary when producing shared objects.
ADD_CXX_FLAGS(-fPIC)
Expand Down
14 changes: 12 additions & 2 deletions build-support/common-build-env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,8 @@ readonly -a VALID_BUILD_TYPES=(
tsan
tsan_slow
pvs
prof_gen
prof_use
)
make_regex_from_list VALID_BUILD_TYPES "${VALID_BUILD_TYPES[@]}"

Expand Down Expand Up @@ -344,7 +346,7 @@ decide_whether_to_use_linuxbrew() {
fi
elif [[ -n ${YB_LINUXBREW_DIR:-} ||
( ${YB_COMPILER_TYPE} =~ ^clang[0-9]+$ &&
$build_type == "release" &&
$build_type =~ ^(release|prof_(gen|use))$ &&
"$( uname -m )" == "x86_64" ) ]]; then
YB_USE_LINUXBREW=1
fi
Expand Down Expand Up @@ -643,6 +645,9 @@ set_cmake_build_type_and_compiler_type() {
tsan_slow)
cmake_build_type=debug
;;
prof_gen|prof_use)
cmake_build_type=release
;;
*)
cmake_build_type=$build_type
esac
Expand All @@ -655,11 +660,16 @@ set_cmake_build_type_and_compiler_type() {
readonly YB_COMPILER_TYPE
export YB_COMPILER_TYPE

if [[ $build_type =~ ^asan|tsan|tsan_slow$ && $YB_COMPILER_TYPE == gcc* ]]; then
if [[ $build_type =~ ^(asan|tsan|tsan_slow)$ && $YB_COMPILER_TYPE == gcc* ]]; then
fatal "Build type $build_type not supported with compiler type $YB_COMPILER_TYPE." \
"Sanitizers are only supported with Clang."
fi

if [[ $build_type =~ ^(prof_gen|prof_use)$ && $YB_COMPILER_TYPE == gcc* ]]; then
fatal "Build type $build_type not supported with compiler type $YB_COMPILER_TYPE." \
"PGO works only with Clang for now."
fi

# We need to set CMAKE_C_COMPILER and CMAKE_CXX_COMPILER outside of CMake. We used to do that from
# CMakeLists.txt, and got into an infinite loop where CMake kept saying:
#
Expand Down
38 changes: 31 additions & 7 deletions build-support/tserver_lto.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,39 @@
activate_virtualenv
set_pythonpath

# usage:
# for release build : ./tserver_lto.sh
# for prof_gen build : ./tserver_lto.sh prof_gen
# for prof_use build : ./tserver_lto.sh prof_use path/to/pgo/data

if [[ $# -gt 0 ]]; then
build_type=$1
validate_build_type "$build_type"
shift
if [[ $build_type == "prof_use" ]]; then
expect_num_args 1 "$@"
pgo_data_path="$1"
shift
fi
else
build_type="release"
fi

if [[ $( uname -m ) == "x86_64" ]]; then
build_root_basename=release-clang12-linuxbrew-full-lto-ninja
build_root_basename="$build_type-clang13-linuxbrew-full-lto-ninja"
else
build_root_basename=release-clang12-full-lto-ninja
build_root_basename="$build_type-clang12-full-lto-ninja"
fi

dep_graph_cmd=(
"${YB_SRC_ROOT}/python/yb/dependency_graph.py"
"--build-root=${YB_SRC_ROOT}/build/${build_root_basename}"
"--file-regex=^.*/yb-tserver$"
)
if [[ $build_type == "prof_use" ]]; then
dep_graph_cmd+=( "--build-args=--pgo-data-path ${pgo_data_path}" )
fi
dep_graph_cmd+=( link-whole-program "$@" )

set -x
"$YB_SRC_ROOT/python/yb/dependency_graph.py" \
--build-root "$YB_SRC_ROOT/build/${build_root_basename}" \
--file-regex "^.*/yb-tserver$" \
link-whole-program \
"$@"
"${dep_graph_cmd[@]}"
31 changes: 31 additions & 0 deletions src/yb/tserver/tablet_server_main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@

#include "yb/tserver/server_main_util.h"

#if defined(YB_PROFGEN) && defined(__clang__)
extern "C" int __llvm_profile_write_file(void);
extern "C" void __llvm_profile_set_filename(const char *);
extern "C" void __llvm_profile_reset_counters();
#endif


using namespace std::placeholders;

using yb::redisserver::RedisServer;
Expand Down Expand Up @@ -159,6 +166,18 @@ void SetProxyAddresses() {
SetProxyAddress(&FLAGS_pgsql_proxy_bind_address, "YSQL", PgProcessConf::kDefaultPort);
}

#if defined(YB_PROFGEN) && defined(__clang__)
// Force profile dumping
void PeriodicDumpLLVMProfileFile() {
__llvm_profile_set_filename("tserver-%p-%m.profraw");
while (true) {
__llvm_profile_write_file();
__llvm_profile_reset_counters();
SleepFor(MonoDelta::FromSeconds(60));
}
}
#endif

int TabletServerMain(int argc, char** argv) {
#ifndef NDEBUG
HybridTime::TEST_SetPrettyToString(true);
Expand Down Expand Up @@ -274,6 +293,13 @@ int TabletServerMain(int argc, char** argv) {
LOG(INFO) << "Redis server successfully started.";
}

#if defined(YB_PROFGEN) && defined(__clang__)
// TODO After the TODO below is fixed the call of
// PeriodicDumpLLVMProfileFile can be moved to the infinite while loop
// at the end of the function.
std::thread llvm_profile_dump_thread(PeriodicDumpLLVMProfileFile);
#endif

// TODO(neil): After CQL server is starting, it blocks this thread from moving on.
// This should be fixed such that all processes or service by tablet server are treated equally
// by using different threads for each process.
Expand Down Expand Up @@ -310,6 +336,11 @@ int TabletServerMain(int argc, char** argv) {
SleepFor(MonoDelta::FromSeconds(60));
}

#if defined(YB_PROFGEN) && defined(__clang__)
// Currently unreachable
llvm_profile_dump_thread.join();
#endif

return 0;
}

Expand Down
17 changes: 17 additions & 0 deletions yb_build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,7 @@ java_only=false
cmake_only=false
run_python_tests=false
cmake_extra_args=""
pgo_data_path=""
predefined_build_root=""
java_test_name=""
show_report=true
Expand Down Expand Up @@ -1041,6 +1042,14 @@ while [[ $# -gt 0 ]]; do
cmake_extra_args+=$2
shift
;;
--pgo-data-path)
ensure_option_has_arg "$@"
pgo_data_path=$(realpath "$2")
shift
if [[ ! -f $pgo_data_path ]]; then
fatal "Profile data file doesn't exist: $pgo_data_path"
fi
;;
--make-ninja-extra-args)
ensure_option_has_arg "$@"
if [[ -n $make_ninja_extra_args ]]; then
Expand Down Expand Up @@ -1354,6 +1363,10 @@ if ! "$build_java" && "$resolve_java_dependencies"; then
fatal "--resolve-java-dependencies is not allowed if not building Java code"
fi

if [[ $build_type == "prof_use" ]] && [[ $pgo_data_path == "" ]]; then
fatal "Please set --pgo-data-path path/to/pgo/data"
fi

# End of post-processing and validating command-line arguments.

# -------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -1524,6 +1537,10 @@ if "$no_tcmalloc"; then
cmake_opts+=( -DYB_TCMALLOC_ENABLED=0 )
fi

if [[ $pgo_data_path != "" ]]; then
cmake_opts+=( "-DYB_PGO_DATA_PATH=$pgo_data_path" )
fi

detect_num_cpus_and_set_make_parallelism
if "$build_cxx"; then
log "Using make parallelism of $YB_MAKE_PARALLELISM" \
Expand Down

0 comments on commit 34cb791

Please sign in to comment.