3

Performance Analysis and Tuning on Modern CPU 中文翻译

 6 months ago
source link: https://weedge.github.io/post/book/performance-analysis-and-tuning-on-modern-cpu-cn/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Performance Analysis and Tuning on Modern CPU 中文翻译

2024-03-01

这是一本名为Performance Analysis and Tuning on Modern CPU书籍的源文件存储库的中文翻译,原版由 Denis Bakhvalov 等人编写。

  • 原版电子书:https://book.easyperf.net/perf_book
  • 中文翻译(第一版):https://book.douban.com/subject/36243215/

原作者第二版正在进行中! 计划的更改在谷歌文档中进行了概述。计划中的新目录在 new_toc.md 中。

目的

  • 虽然已经有翻译的书籍;但是想follow更新,借助 『chatGPT』/『gemini/moonshot(kimi)』 翻译成中文,(加速学习节奏,掌握,并举一反三)
  • 英文源书是开源的,翻译成中文工作也持续更新,也是开源的,可以作为学习资料, 在线阅读可编辑,希望一起参与改进。
  • 对每章节的内容通过 『chatGPT』/『gemini/moonshot(kimi)』 进行归纳总结,结巩固知识点,并对课后练习进行回答,并验证答案。
  • 最后整体勘误,定搞。

[!TIP]

  • 授之以鱼不如授之以渔, 使用AI赋能。
  • 性能优化分析数据可以借助『chatGPT』分析。
  • 『chatGPT』和『moonshot(kimi)』 翻译效果差不多(相同的prompt),但是当问文中的规划练习和代码练习时,『moonshot(kimi)』不能理解问题,不过长文本上传根据章节翻译和归纳总结不错,毕竟不用翻墙就可以使用。

在线阅读地址: https://weedge.github.io/perf-book-cn/zh/

中文版PDF(推荐): https://raw.githubusercontent.com/weedge/perf-book-cn/main/perf-book-cn.pdf

[!TIP]

[!NOTE]

  1. 在写代码时或多或少会知道一些代码层次(比如c++)的优化,但可能不知道为啥是这样的,这本书结合cpu讲解了相关原理(比如unlikely,likely)。
  2. 木桶效应,通过监控测量分析,寻找性能短板在哪,结合场景对症下药(理解工作原理)
  3. 了解现代cpu微体系架构(本文中提到的 Intel GoldenCove 架构白皮书@IntelOptimizationManual), 以小见大, 设计思路借鉴到业务系统中(虽然有些详细信息未公开)
  4. AMD处理器 @AMDProgrammingManual ; ARM Neoverse V1处理器 @ARMNeoverseV1
  5. 书中一些case介绍了优化工具的使用和性能分析
  6. 阅读本书不需要详细了解每个性能分析工具的使用(比如常用的perf),主要是针对cpu特性,memory的性能分析;只要记住有这个工具干啥用的,当遇到性能分析场景时,可以再次查阅该工具的使用方法即可;主要是结合工具去实践总结方法论。
  7. 本书是针对现代CPU的性能分析和优化;前提条件是应用程序已经消除所有主要性能问题;如果想更深层次优化(比如底层存储系统, 流量请求最终汇聚点系统,核心系统等),可以使用 CPU 性能监控功能来分析和进一步调整应用程序。仅当所有高级性能问题都已修复后,才建议使用硬件功能进行低级微调。在设计不良的算法系统上进行cpu分析调优只是时间上的浪费。
  8. 底层硬件的持续性能分析(CP)在IaaS/PaaS云服务企业中常见。
  9. 延伸阅读:brendangregg-systems-performance | brendangregg-bpf-performance 必备性能分析工具书(函方法论实践)
  10. 利用人工智能和 LLM 启发架构来处理性能分析样本,分析 函数之间关系,最终高精度地找出直接影响整体吞吐量和延迟的函数和库。Raven.io提供这种功能的一家公司
  11. 源代码优化章节重点掌握
  12. 编译链接层面静态分析,通过优化报告(比如: GCC的-fopt-info;clang使用-Rpass*)来获取优化建议(需要实践测试)
  13. PGO 基于性能分析引导的优化(Profile Guided Optimizations) 练习: https://github.com/dendibakh/perf-ninja/blob/main/labs/misc/pgo/README.md (PGO 主要用于具有大型代码库的项目,比如:数据库,分布式文件系统); 特地场景,谨慎分析配置引导优化(可组合)。
  14. 充分考虑到时间局部性和空间局部性对性能的影响
  15. 尽量做扩展阅读,比如作者的博客文章,相关引用(比如:@fogOptimizeCpp)
  16. 对于cpu性能优化,有些已在编译器层面进行了优化,比如机器代码布局
  17. 关注低延迟系统的性能优化 (比如HFT系统中的这个快速演讲:CppCon 2018: Jonathan Keinan “Cache Warming: Warm Up The Code”; 这些关键路径代码值钱)
  18. 优化多线程应用:
    1. 借助可视化分析工具进行分析定位性能瓶颈(同步事件,锁,上下文切换),书中举了一些case, Intel VTune Profiler 这个工具对于作者来说经常使用, 类似GPU性能分析工具 nsight-compute (通过nsight-systems分析系统整体性能耗时);
    2. 通过eBPF追踪内核中 futex 系统调用的执行(内核通过 futex 系统调用支持线程同步原语 - 互斥锁、信号量、条件变量等),从涉及的线程中收集有用的元数据
    3. 尽量避免真共享下的数据竞争问题,通过编译器集成的 sanitizers 工具来识别,比如Clang Thread sanitizer
    4. 避免伪共享。由于多核处理器cpu之间独立的L1/L2 cache,会出现cache line不一致的问题,为了解决这个问题,有相关协议模型,常用MESI协议,MESI 通过 这个网站模拟更直观的了解 https://www.scss.tcd.ie/Jeremy.Jones/VivioJS/caches/MESIHelp.htm ;为了保证一个core上修改的cache line数据同步到其他core的cache line上,则需要MESI协议来保证,如果同一个cache line上有个两个变量sum1 和 sum2 之间虽然没有相互依赖逻辑,但是当修改sum1 或者sum2 时,需要同步同一块cache line的内容,导致 即使没有相互关系的变量在同一cache line中, 需要彼此共享同步,从而出现所说的伪共享 flase sharing。伪共享因为cache line的同步会带来一些cpu 时钟周期的性能损失。
    5. 深入了解并行编程: Is Parallel Programming Hard, And, If So, What Can You Do About It?

[!TIP] 由于多核处理器cpu之间独立的L1/L2 cache,会出现cache line不一致的问题,为了解决这个问题,有相关协议模型,比如MESI协议来保证cache数据一致,同时由于CPU对「缓存一致性协议」进行的异步优化,对写和读分别引入了「store buffer」和「invalid queue」,很可能导致后面的指令查不到前面指令的执行结果(各个指令的执行顺序非代码执行顺序),这种现象很多时候被称作「CPU乱序执行」,为了解决乱序问题(也可以理解为可见性问题,修改完没有及时同步到其他的CPU),又引出了「内存屏障」的概念;内存屏障可以分为三种类型:写屏障,读屏障以及全能屏障(包含了读写屏障),屏障可以简单理解为:在操作数据的时候,往数据插入一条”特殊的指令”。只要遇到这条指令,那前面的操作都得「完成」。CPU当发现写屏障指令时,会把该指令「之前」存在于「store Buffer」所有写指令刷入高速缓存。就可以让CPU修改的数据马上暴露给其他CPU,达到「写操作」可见性的效果。读屏障也是类似的:CPU当发现读屏障的指令时,会把该指令「之前」存在于「invalid queue」所有的指令都处理掉。通过这种方式就可以确保当前CPU的缓存状态是准确的,达到「读操作」一定是读取最新的效果。由于不同CPU架构的缓存体系不一样、缓存一致性协议不一样、重排序的策略不一样、所提供的内存屏障指令也有差异,所以一些语言c++/java/go/rust 都有实现自己的内存模型, 比如 golang大牛Russ Cox写的内存模型系列文章 Memory Models: https://research.swtch.com/mm 值得深入了解

文章作者 weedge

上次更新 2024-03-01

许可协议 CC BY-NC-ND 4.0

上一篇 下一篇


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK