ReorderData - 优化阅读笔记

时间:2024-03-13 15:27:04

主要实现文件: bolt/lib/Passes/ReorderData.cpp

支持 X86/Arm
测试用例: bolt/test/reorder-data-writable-ptload.c

int a1,a2,a3,a4;
// 待补充

默认关闭,开启选项:

# 指定要重排的数据段
--reorder-data=<section1,section2,section3,...>
# 重排算法
--reorder-data-algo=count/funcs
# 重排后原地替换,暂不支持
--reorder-data-inplace

# 限制新的数据段的大小
--reorder-data-max-bytes=<uint>    -- default std::numeric_limits<unsigned>::max()
# 限制新的数据段的符号数量
--reorder-data-max-symbols=<uint>  -- default std::numeric_limits<unsigned>::max()

注: objdump -D 命令把 .data 段当成指令来解析了,看起来分成奇怪,我们只要看数据就行,这里想要展示的是常用的 .data 段数据被放到一起了,减少 dcache miss
在这里插入图片描述

void ReorderData::assignMemData(BinaryContext &BC) {
  // 采样文件需要包含下面这种 Memory Profile
  // 4 _start 0 4 hot1 0 100

  // 查找包含 "MemoryAccessProfile" 注释的指令
  BC.MIB->tryGetAnnotationAs<MemoryAccessProfile>(Inst, "MemoryAccessProfile");
/********************************
.LBB00:
    00000000:   incl    hot1(%rip) # MemoryAccessProfile: 100 total counts :
        { hot1 + 0x0: 100 }
    00000006:   jmp     .LBB00
preds: .LBB00
succs: .LBB00
********************************/
  // 遍历指令访问的所有数据段
  for (const AddressAccess &AccessInfo : MemAccessProfile.AddressAccessInfo) {
    // 存储数据段的访问计数
    BinaryDataCounts[BD->getAtomicRoot()] += AccessInfo.Count;
}
void ReorderData::runOnFunctions(BinaryContext &BC) {

  // 必须指定要重排的数据段
  if (!BC.HasRelocations || opts::ReorderData.empty())

  // 不能与跳转表优化一起工作
  if (opts::JumpTables > JTS_BASIC)

  assignMemData(BC);

  // 根据选项提供的名字找到实际 Section 地址
  for (const std::string &SectionName : opts::ReorderData)

  for (BinarySection *Section : Sections) {

    // 检查 "PG." 开头的 Section 和 有重叠的 Section
    // 当前私有符号无法移动,因为数据可能会在一个符号的边界之间"泄露"到另一个符号,例如,一个具有共同后缀的字符串可能从一个私有符号开始,并在另一个符号中以共同的后缀结尾
    const bool FoundUnmoveable = markUnmoveableSymbols(BC, *Section);

    std::tie(Order, SplitPointIdx) = sortedByCount(BC, *Section);
    std::tie(Order, SplitPointIdx) = sortedByFunc(BC, *Section, BC.getBinaryFunctions());

    setSectionOrder(BC, Hot, Order.begin(), SplitPoint);
}

遗留问题:

  1. 怎么产生内存相关的采样数据 - 检查了 mysql 的采样文件未发现这种数据
  2. 能否通过增强插桩生成这种数据