热点函数重排

https://gitee.com/ijinma/hfsort
https://web.archive.org/web/20170729173320id_/https://research.fb.com/wp-content/uploads/2017/01/cgo2017-hfsort-final1.pdf

函数重排(Function Reordering)优化原理与 TLB 性能分析
通过函数重排(或 代码布局优化)将热点代码聚合到紧凑的 __TEXT 段,可以显著提高 iTLB(Instruction Translation Lookaside Buffer) 的缓存命中率,从而提升程序性能。以下是详细分析:

  1. TLB 的作用与性能影响
    TLB 本质:
    用于缓存 虚拟地址到物理地址的映射关系,减少多级页表查询的访存开销。
    TLB 层级:
    iTLB:缓存指令地址的页表映射(__TEXT 段)。
    dTLB:缓存数据地址的页表映射(__DATA、栈、堆等)。
    TLB Miss 代价:
    若页表项未命中 TLB,需遍历多级页表(可能触发 4~5 次内存访问),导致性能急剧下降。
image.png

image.png

从数据上看,函数重排对itlb的命中率影响很大

perf stat -e dTLB-loads,dTLB-load-misses,iTLB-loads,iTLB-load-misses -p 58029

image.png

image.png

TLB(Translation Lookaside Buffer),专门用于改进虚拟地址到物理地址转换速度的缓存。其访问速度非常快,和寄存器相当,比L1访问还快。但是TLB并不是很大只有4k,一旦TLB miss造成的后果可比物理地址cache miss后果要严重一些,最多可能需要进行5次内存IO 【多级页表】

由此初步分析出:热点函数重排后让关键代码变的更紧凑,极大增加了TLB的缓存命中率,从而提升了CPU的运行效率,进而提升了服务的性能

实现函数重排的技术手段


image.png

(1) 编译器优化
GCC/Clang: 使用 -freorder-functions 或 Profile-Guided Optimization (PGO):
bash
步骤 1: 生成运行时 Profile 数据
./program <训练输入>

步骤 2: 根据 Profile 重新编译
gcc -fprofile-use -freorder-functions -O3 program.c -o program_optimized

(2) 链接时优化(LTO)
使用链接器脚本(Linker Script)控制函数顺序:
ld
SECTIONS {
.text : {
/* 按调用频率排序函数 */
hot_functions.o(.text.)
(.text.)
}
}
(3) 运行时重排工具
BOLT (Binary Optimization and Layout Tool):
基于执行 Profile 的二进制重排工具(无需源码):
bash
生成 Profile
perf record -e cycles:u -j any,u -o perf.data -- ./program

应用重排优化
llvm-bolt program -o program.bolt -data perf.data -reorder-blocks=ext-tsp -reorder-functions=hfsort

其他补充优化
大页(Huge Pages):
使用 2MB 或 1GB 大页减少 TLB 压力(需内核支持)。
bash
分配 2MB 大页
echo 2048 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages
代码段对齐:
将热点函数对齐到缓存行(Cache Line)边界,减少跨页访问。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容