Profiler 的类型
LLVM 已经内置了一个可对代码进行插桩的工具,使我们能够进行插桩分析。与采样分析或统计分析相比, 这种方式精度非常高,不会漏掉任何调用,但代价是需要对代码进行插桩,并且资源开销更大。
简单来说,插桩分析器会插入额外的代码,以跟踪对所有函数的调用。 统计分析器则允许我们在不修改代码的情况下运行程序,通过定期获取快照来查看应用程序的状态。因此,只有在获取快照时正在运行的函数才会被统计。perf 是一个非常知名的 统计分析器。
使用 XRay 的集成功能分析 ClickHouse 性能
在 ClickHouse 25.12 中,XRay 已完成集成,可无缝为函数添加新的插桩点。 因此,任何官方发布版本都已包含此功能,并且可按需触发;在未启用时, 不会影响整体性能。其思路是仅启用尽可能少的 插桩点,以获取有价值的信息。
我们可以使用 SYSTEM INSTRUMENT ADD
PROFILE
语句添加一个新的性能分析插桩点。可插桩的函数可以从
system.symbols 系统表中获取。比如,我们
想分析 sleepForNanoseconds 函数的性能,它很适合用来检查运行耗时。
SYSTEM INSTRUMENT ADD 'sleepForNanoseconds' PROFILE然后,让它在我们想要分析的时间段内持续运行,再将其停止。
SYSTEM INSTRUMENT REMOVE ALL我们将 system.trace_log 中收集的数据转换为Chrome 格式,以便在 Perfetto 中可视化。请注意每个条目的 query_id、cpu_id 和 stacktrace。

使用 XRay 对原生应用程序进行性能分析
以下内容保留为参考,帮助你了解 XRay 的底层工作机制,以及如何开箱即用地用它对原生应用程序进行性能分析。
对代码进行插桩
假设有如下源代码:
#include <chrono>
#include <cstdio>
#include <thread>
void one()
{
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
void two()
{
std::this_thread::sleep_for(std::chrono::milliseconds(5));
}
int main()
{
printf("Start\n");
for (int i = 0; i < 10; ++i)
{
one();
two();
}
printf("Finish\n");
}要使用 XRay 进行插桩,需要添加一些参数,如下所示:
clang++ -o test test.cpp -fxray-instrument -fxray-instruction-threshold=1- 需要使用
-fxray-instrument为代码插桩。 - 使用
-fxray-instruction-threshold=1是为了让它对所有函数都进行插桩,即使它们 像本例中那样非常小。默认情况下,它只会对至少有 200 条 指令的函数进行插桩。
我们可以通过检查可执行文件中是否新增了一个 section,来确认代码已正确插桩:
objdump -h -j xray_instr_map test
test: file format elf64-x86-64
Sections:
Idx Name Size VMA LMA File off Algn
17 xray_instr_map 000005c0 000000000002f91c 000000000002f91c 0002f91c 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA使用适当的环境变量值运行进程以收集 trace
默认情况下,除非显式启用,否则 Profiler 不会收集数据。换句话说,除非
我们正在进行 profiling,否则其开销几乎可以忽略不计。我们可以为 XRAY_OPTIONS 设置不同的值,
以配置 Profiler 何时开始收集,以及采用何种方式收集。
XRAY_OPTIONS="patch_premain=true xray_mode=xray-basic verbosity=1" ./test
==74394==XRay: Log file in 'xray-log.test.14imlN'
Start
Finish
==74394==Cleaned up log for TID: 74394转换 trace
XRay 的 trace 可以转换为多种格式。trace_event 格式非常有用,因为
它便于解析,而且已有不少工具支持,因此我们将使用这种格式:
llvm-xray convert --symbolize --instr_map=./test --output-format=trace_event xray-log.test.14imlN | gzip > test-trace.txt.gz将 trace 可视化
我们可以使用基于 Web 的 UI,例如 speedscope.app 或 Perfetto。
虽然 Perfetto 更便于同时可视化多个线程并查询数据,但 speedscope 更适合 生成火焰图以及数据的三明治视图。
按时间顺序

左偏重

三明治

查阅文档
- SYSTEM INSTRUMENT — 添加 或移除插桩点。
- system.instrumentation — 查看已插桩的点位。
- system.symbols — 查看 可用于添加插桩点的符号。
- system.trace_log — 查看通过插桩点收集的 数据。
- XRay Instrumentation
- 使用 XRay 进行调试 文档以了解更多详情。