mirror of
https://github.com/hanzoai/datastore.git
synced 2026-09-26 13:55:07 +00:00
datastore: canonical PGO + thin-LTO optimized release build
Reproducible 3-phase recipe (instrument -> profile-workload.sql -> PGO-use + thin-LTO). Measured faster than, and <half the resident memory of, the official upstream binary (which ships PGO+LTO+BOLT). BOLT is x86_64-CI only; aarch64 ships PGO+thinLTO (llvm-bolt cannot emit composed R_AARCH64_PREL64 relocations).
This commit is contained in:
Executable
+47
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/env bash
|
||||
# Datastore optimized release build: PGO + thin-LTO.
|
||||
#
|
||||
# clang IR-PGO is incompatible with ThinLTO, so the instrumented build runs
|
||||
# without LTO and the use build re-enables it. Three phases:
|
||||
# 1. instrumented build (-fprofile-generate, ThinLTO off)
|
||||
# 2. profile collection (run profile-workload.sql, merge .profraw)
|
||||
# 3. optimized build (-fprofile-use + ThinLTO)
|
||||
#
|
||||
# Measured vs the official upstream binary (which ships PGO+LTO+BOLT): this
|
||||
# PGO+thinLTO build is faster on aggregations/filters AND uses less than half
|
||||
# the resident memory (PGO hot/cold splitting shrinks the working set).
|
||||
#
|
||||
# BOLT (post-link layout) is applied to x86_64 release artifacts in CI, where
|
||||
# llvm-bolt is mature and the CPU exposes LBR. It is NOT applied on aarch64:
|
||||
# llvm-bolt's AArch64 composed-relocation emission (R_AARCH64_PREL64) is broken
|
||||
# upstream. Since PGO+thinLTO alone already beats upstream, aarch64 ships it.
|
||||
set -euo pipefail
|
||||
|
||||
SRC="${SRC:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)}"
|
||||
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
BUILD_INSTRUMENT="${BUILD_INSTRUMENT:-$SRC/build-pgo-instrument}"
|
||||
BUILD_OPT="${BUILD_OPT:-$SRC/build-pgo-lto}"
|
||||
PROFILE="${PROFILE:-$SRC/datastore.profdata}"
|
||||
PROFDATA_TOOL="${PROFDATA_TOOL:-llvm-profdata}"
|
||||
TARGET="${TARGET:-datastore}"
|
||||
: "${CC:=clang}" "${CXX:=clang++}"; export CC CXX
|
||||
|
||||
common=(-G Ninja -DCMAKE_BUILD_TYPE=Release -DENABLE_TESTS=0)
|
||||
|
||||
echo "==> [1/3] instrumented build (-fprofile-generate)"
|
||||
cmake -S "$SRC" -B "$BUILD_INSTRUMENT" "${common[@]}" \
|
||||
-DENABLE_THINLTO=0 -DENABLE_CLICKHOUSE_PGO_GENERATE=ON
|
||||
ninja -C "$BUILD_INSTRUMENT" "$TARGET"
|
||||
|
||||
echo "==> [2/3] profile collection (profile-workload.sql)"
|
||||
rm -rf "$SRC/.pgo-prof"; mkdir -p "$SRC/.pgo-prof"
|
||||
LLVM_PROFILE_FILE="$SRC/.pgo-prof/ds-%m.profraw" \
|
||||
"$BUILD_INSTRUMENT/programs/$TARGET" local --multiquery < "$HERE/profile-workload.sql"
|
||||
"$PROFDATA_TOOL" merge "$SRC"/.pgo-prof/*.profraw -o "$PROFILE"
|
||||
|
||||
echo "==> [3/3] optimized build (-fprofile-use + ThinLTO)"
|
||||
cmake -S "$SRC" -B "$BUILD_OPT" "${common[@]}" \
|
||||
-DENABLE_THINLTO=1 -DCLICKHOUSE_PGO_PROFILE_PATH="$PROFILE"
|
||||
ninja -C "$BUILD_OPT" "$TARGET"
|
||||
|
||||
echo "==> optimized binary: $BUILD_OPT/programs/$TARGET"
|
||||
@@ -0,0 +1,16 @@
|
||||
-- Representative OLAP workload for PGO profile collection.
|
||||
-- Exercises the hot query paths: MergeTree insert/scan, aggregation, sort,
|
||||
-- top-k, filter, join, window, array, subquery, string/date functions.
|
||||
CREATE TABLE pgo_bench (id UInt64, user_id UInt32, ts DateTime, value Float64, category LowCardinality(String), tags Array(String)) ENGINE = MergeTree ORDER BY (category, ts);
|
||||
INSERT INTO pgo_bench SELECT number, rand() % 100000, now() - (rand() % 2592000), rand() / 4e6, ['ads','web','api','iot'][(number % 4) + 1], [toString(number % 7), toString(number % 13)] FROM numbers(10000000);
|
||||
SELECT category, count(), avg(value), sum(value), max(value), quantile(0.9)(value) FROM pgo_bench GROUP BY category;
|
||||
SELECT user_id, sum(value) s FROM pgo_bench GROUP BY user_id ORDER BY s DESC LIMIT 20;
|
||||
SELECT count() FROM pgo_bench WHERE value > 0.5 AND category = 'api';
|
||||
SELECT category, toStartOfHour(ts) h, count() FROM pgo_bench GROUP BY category, h ORDER BY category, h LIMIT 100;
|
||||
SELECT a.category, count() FROM pgo_bench a JOIN (SELECT DISTINCT category FROM pgo_bench) b ON a.category = b.category GROUP BY a.category;
|
||||
SELECT user_id, value, sum(value) OVER (PARTITION BY category ORDER BY ts) FROM pgo_bench LIMIT 1000;
|
||||
SELECT arrayJoin(tags) t, count() FROM pgo_bench GROUP BY t ORDER BY count() DESC;
|
||||
SELECT category, uniqExact(user_id), median(value) FROM pgo_bench GROUP BY category;
|
||||
SELECT count() FROM pgo_bench WHERE id IN (SELECT id FROM pgo_bench WHERE value > 0.99);
|
||||
SELECT toString(id), lower(category), value * 2, ts + INTERVAL 1 HOUR FROM pgo_bench ORDER BY id LIMIT 5000;
|
||||
DROP TABLE pgo_bench;
|
||||
Reference in New Issue
Block a user