问题与练习

  1. 解决 perf-ninja::pgo 实验作业。
  2. 尝试为代码段使用大页。选择一个大型应用程序(如果能够访问源代码则更佳,但不是必需的),其二进制文件大小超过100MB。尝试使用 [@sec:FeTLB] 中描述的一种方法将其代码段重新映射到大页上。观察性能的任何变化,/proc/meminfo 中的大页分配情况,以及测量 ITLB 命中和未命中的 CPU 性能计数器。
  3. 假设你有一段代码,其中包含一个循环中的 C++ switch 语句。你已经对代码进行了分析,并发现 switch 语句中的一个特定情况占了 70% 的时间。其他 40 种情况每种使用时间不到 3%,另外 20 种情况从未发生。你会如何优化这个 switch/循环的性能?
  4. 在你日常使用的应用程序上运行 PGO、llvm-bolt 或 Propeller。比较“优化前”和“优化后”的性能分析,以了解加速来自何处。

AI回答:

  1. 解决 perf-ninja::pgo 实验作业

    • 首先,确保你有一个支持PGO(Profile Guided Optimizations)的编译环境,比如GCC或Clang。
    • 编译你的程序,启用PGO插桩(instrumentation),这通常涉及到添加特定的编译器标志,如-fprofile-instr-generate
    • 使用你的程序运行一系列代表性的工作负载,以收集性能数据。这通常涉及到运行程序多次,或者使用特定的工具来收集运行时数据。
    • 分析收集到的性能数据,这可能包括函数调用次数、循环迭代次数等。
    • 使用这些数据重新编译你的程序,启用PGO使用(-fprofile-use)来生成优化后的二进制文件。
    • 测试优化后的程序,比较性能提升。
  2. 尝试为代码段使用大页

    • 选择一个大型应用程序,确保其二进制文件大小超过100MB。
    • 在Linux系统上,你可以使用madvise系统调用来建议内核使用大页。例如,madvise((void *)address, size, MADV_HUGEPAGE)
    • 另一种方法是在编译时使用特定的链接器选项,如-Wl,-zmax-page-size=2M,这会告诉链接器尝试将代码段放置在2MB大页上。
    • 观察性能变化,可以通过运行基准测试来完成。
    • 查看/proc/meminfo文件来确认大页的使用情况。
    • 使用性能分析工具(如perf)来测量ITLB的命中和未命中情况。
  3. 优化C++ switch语句

    • 对于频繁执行的特定情况,可以考虑将其提取到一个单独的函数中,以减少switch语句的复杂性。
    • 对于从未发生的分支,可以完全移除它们,以简化switch语句。
    • 对于使用频率较低的分支,可以考虑使用跳转表(jump table)或者基于范围的switch来优化。
    • 如果switch语句基于某些可预测的模式(如枚举类型),可以考虑使用位掩码或查找表来加速决策过程。
  4. 运行PGO、llvm-bolt或Propeller

    • 对于PGO,按照上述步骤1的指导进行。
    • 对于llvm-bolt,可以使用llvm-bolt工具对二进制文件进行优化。这通常涉及到反汇编代码,应用优化,然后重新链接。
    • 对于Propeller,这是一个二进制重链接工具,它依赖于链接器输入,可以在多个机器上分布式运行。
    • 在优化前后,使用性能分析工具(如perf)来比较性能指标,如CPU周期、缓存命中率等,以了解性能提升的来源。

results matching ""

    No results matching ""