
3.3.1《现代CPU的性能分析和调优》
文章平均质量分 83
https://download.youkuaiyun.com/download/u012906122/88732265?spm=1001.2014.3001.5503
hyh-hz
书是越读越薄的
展开
-
Appendix B. The LLVM Vectorizer
SIMD向量中的每个通道在连续的循环迭代上执行独立的算术操作。在下面的循环中,迭代的起始点和结束点未知,而向量化器有一种机制可以对不从零开始的循环进行向量化。向量化器能够处理这些控制流程,使得循环的操作可以以向量化的方式执行,从而提高代码的效率和性能。LLVM循环向量化器可以检测到这些内部数学函数,并将其转化为相应的向量指令,以在向量级别上执行计算,提高代码的执行效率和性能。在下面的示例中,如果指针A和B指向连续的地址,则对代码进行向量化是不允许的,因为一些A的元素会在从数组B读取之前被写入。翻译 2023-08-05 11:16:40 · 247 阅读 · 0 评论 -
Appendix A. Reducing Measurement Noise
这意味着如果我们在同一个核心上以“同时”的方式运行两个独立的进程(在不同的线程中),它们可以相互竞争资源,例如缓存空间。如果使用Linux perf工具,请至少保留两个核心,这样perf会在一个核心上运行,而您的程序会在另一个核心上运行。其中之一是为了节省功耗,在这种情况下,Linux内核中的频率调整策略(Scaling Governor)可以决定降低CPU运行频率。通过增加优先级,进程将获得更多的CPU时间,并且Linux调度器将更倾向于优先处理该进程,而不是普通优先级的进程。翻译 2023-08-05 10:46:33 · 98 阅读 · 0 评论 -
Epilog
我很愿意听取您对这本书的反馈意见,您可以通过我的电子邮件dendibakh@gmail.com与我联系。希望这本书能帮助您更好地理解您的应用程序性能和CPU性能的一般情况。当然,它并没有涵盖您在进行性能优化工作时可能遇到的所有可能场景。我的目标是给您一个起点,并向您展示在现代CPU上处理性能分析和调优的潜在选择和策略。在不久的将来,它将是性能提升的关键驱动因素之一。硬件和软件组件都有这样的限制。• 现代系统的性能是不确定的,取决于许多因素。• 有时,改进一个系统上的性能可能会减慢另一个系统上的执行速度。翻译 2023-08-05 10:35:56 · 94 阅读 · 0 评论 -
11 Optimizing Multithreaded Applications
GAPP使用eBPF来跟踪多线程应用程序的争用开销,通过对已识别的串行化瓶颈的重要性进行排名,收集被阻塞的线程和导致阻塞的线程的堆栈跟踪信息。从性能的一般角度考虑,最重要的是考虑可能的状态转换的成本。例如,我们可以看到在从1秒到3秒的时间间隔内,只有两个线程持续地利用了相应的CPU核心的约100%(TID为7675和7678的线程)。如果没有这样的协议,如果CPU A和CPU B都将内存位置L读入其各自的缓存中,并且处理器B随后修改了其缓存中L的值,那么这两个CPU会对相同内存位置L拥有不一致的值。翻译 2023-08-05 10:32:38 · 237 阅读 · 0 评论 -
10 Other Tuning Areas
然而,这只是一个一般的指导方针,正如本书中所强调的一切,最好根据自己的实际情况进行测量。然而,还有几个注意事项。然后,就在我们需要执行那个关键但很少执行的代码片段时,我们遇到了I-cache和D-cache的缺失惩罚,这可能超过我们的目标性能预算。内置函数具有与内联汇编相同的好处,但同时提高了代码的可读性,允许编译器类型检查,帮助指令调度,并有助于减少调试工作。即使是经过高度调优的应用程序,如果遭遇系统管理中断(SMI),即整个操作系统被停止以执行固件代码的BIOS中断,那么它的意义也将变得微乎其微。翻译 2023-08-05 10:18:58 · 93 阅读 · 0 评论 -
9 Optimizing Bad Speculation
对于Listing 44中的代码片段,CPU可以选择if条件的true分支,并继续以a = computeX()的值进行代码的推测执行。对于Listing 45中的代码,这种推测是不可能的,因为CPU不能在CMOVNE指令完成之前发出使用a的加载指令。在这种情况下,预测错误的代价远大于内存访问的代价,因此无法获得推测执行带来的好处。1. 对于一个大数组的搜索,该数组不适合存储在CPU缓存中,基于分支的二分查找版本表现更好,因为与内存访问的延迟相比(由于缓存未命中而较高),分支预测错误的代价较低。翻译 2023-08-05 09:37:16 · 187 阅读 · 0 评论 -
8 CPU Back-End Optimizations
CPU后端(BE)组件在第3.8.2节中进行了讨论。大部分情况下,CPU后端的低效率可以描述为FE已经获取和解码指令,但是BE负载过重,无法处理新指令。从技术上讲,这是一种FE无法传递uops的情况,因为后端缺乏接受新uops所需的资源。其中一个例子是由于数据缓存未命中或除法器负载过重而导致的停顿。我想强调给读者的建议是,只有当TMA指向较高的“后端限制”指标时,才建议开始优化针对CPU后端的代码。TMA进一步将后端限制指标分为两个主要类别:内存限制和核心限制,我们将在接下来进行讨论。8.1 Memory翻译 2023-08-02 01:14:16 · 582 阅读 · 0 评论 -
7 CPU Front-End Optimizations
然而,在这个特定的例子中,我们知道coldFunc是一个处理错误的函数,并且可能不经常被执行。通过选择41b的布局,我们保持了代码热点之间的顺序执行,并将已执行的分支转换为未执行的分支。幸运的是,它不一定要完全是单个工作负载,因为可以将来自不同工作负载的性能分析数据合并在一起,代表应用程序的一组用例。例如,当将UNLIKELY提示应用于本节中的原始示例时,编译器会阻止对coldFunc的内联,因为现在它知道coldFunc不太可能经常执行,而优化其大小更有益,即只保留对该函数的调用。翻译 2023-08-02 00:49:02 · 257 阅读 · 0 评论 -
Part2. Source Code Tuning For CPU
传统上,链表的每个新节点都是动态分配的。然而,如果程序在数据结构上进行迭代并且对对象的所有字段(即a、b、c)执行过多的操作,则AOS更好,因为结构的所有成员很可能位于同一缓存行中。幸运的是,通过我们在第6节中讨论的所有性能监控功能,我们可以知道从CPU的角度看,你的代码是什么样子。链表的缺点包括无法通过索引直接访问元素、占用更多的内存空间(由于存储了指向下一个节点的指针)和遍历时需要更多的时间(需要通过指针逐个访问节点)。个人经验:事实上,我们可以说,在某种程度上,所有的优化都是数据驱动的。翻译 2023-08-02 00:29:13 · 104 阅读 · 0 评论 -
6 CPU Features For Performance Analysis
性能分析的最终目标是确定瓶颈并找到与之相关联的代码位置。不幸的是,没有预定的步骤可以遵循,因此可以以许多不同的方式进行处理。通常,对应用程序进行分析可以快速了解应用程序的热点。有时,这是开发人员需要做的一切来修复性能低效。尤其是高级性能问题通常可以通过分析揭示。例如,考虑这样一种情况,你使用感兴趣的特定函数对应用程序进行分析。根据你对应用程序的心理模型,你预计该函数是不经常使用的。但是,当你打开分析文件时,你会发现它消耗了大量的时间并且被调用了很多次。基于这些信息,你可以应用缓存或记忆化等技术来减少对该函翻译 2023-08-01 23:35:40 · 878 阅读 · 0 评论 -
5 Performance Analysis Approaches
进行高级优化时,通常很容易判断性能是否得到改善。当您编写算法的更好版本时,您希望看到程序运行时间的明显差异。但是,有时候您会看到执行时间的变化,但是您不知道它来自哪里。单独的时间无法提供任何关于发生这种情况的原因的见解。在这种情况下,我们需要更多关于程序执行方式的信息。这是我们需要进行性能分析以了解所观察到的减速或加速的底层本质的情况。我们的程序运行时,硬件和软件都会跟踪性能数据。在这种情况下,所谓的硬件是指执行程序的CPU,而所谓的软件是指操作系统和所有用于分析的工具。通常,软件堆栈提供高级度量标准,如翻译 2023-08-01 22:42:11 · 815 阅读 · 0 评论 -
4 Terminology and metrics in performance analysis
但是,对于执行的预测指令,CPU会保留它们的结果而不会立即提交它们的结果。例如,一个简单的加法指令,如ADD EAX,EBX只会生成一个µop,而更复杂的指令,如ADD EAX,[MEM1]可能会生成两个µops:一个用于从内存中读取到一个临时(未命名)寄存器中,另一个用于将临时寄存器中的内容与EAX相加。在这个过程中,线程需要等待一定的时间,这就导致了它在这段时间内无法执行任何指令,虽然此时线程不再占用CPU时间片,但是CPU还是需要对其进行调度,使其进入等待队列和唤醒队列中。这也称为“推测执行”。翻译 2023-08-01 22:25:14 · 488 阅读 · 0 评论 -
3 CPU Microarchitecture
本章简要概述了对性能有影响的关键CPU架构和微架构特征。本章的目标不是详细介绍CPU架构的细节和权衡,在文献中已有广泛介绍[Hennessy和Patterson,2011]。我们将快速回顾对软件性能产生直接影响的CPU硬件特征。3.1 Instruction Set Architecture指令集是软件与硬件通信时使用的词汇。指令集架构(ISA)定义了软件和硬件之间的约定。Intel x86、ARM v8、RISC-V是当前最广泛部署的ISA的示例。所有这些都是64位体系结构,即所有地址计算都使用64位。翻译 2023-08-01 01:45:04 · 498 阅读 · 0 评论 -
2 Measuring Performance
2.1 Noise In Modern Systems硬件和软件中有许多旨在提高性能的功能,但并不是所有功能都具有确定性行为。让我们考虑动态频率缩放(DFS):这是一项功能,允许CPU在短时间间隔内增加频率,使其运行速度显著提高。然而,CPU不能长时间保持在“超频”模式下,因此稍后会将频率降回基准值。DFS通常非常依赖核心温度,这使得难以预测其对实验的影响。如果我们在“冷”处理器上连续进行两次基准测试运行,第一次运行可能会在“超频”模式下运行一段时间,然后将频率降回基准水平。然而,第二次运行可能没有这个翻译 2023-08-01 01:17:46 · 139 阅读 · 0 评论 -
Part1. Performance analysis on a modern CPU
对于关注性能评估的任何人来说,都知道进行公平性能测量并从中得出准确结论有多么困难。本章专门介绍了在持续集成和持续交付(CI / CD)系统中跟踪性能变化的自动化过程,同时也提供了有关开发人员在实现源代码更改时如何正确收集和分析性能测量结果的一般指导。设计性能测试和配置环境都是评估性能过程中重要的组成部分。例如,在解压缩zip文件时,我们会一遍又一遍地得到相同的结果,这意味着这个操作是可重现的。本章末尾描述了可以由开发人员用于基于时间的测量的SW和HW计时器以及设计和编写良好的微基准测试时常见的陷阱。翻译 2023-08-01 00:57:07 · 136 阅读 · 0 评论 -
1 Introduction
他们说,“性能至上”。这在十年前是正确的,现在也同样正确。根据[Dom, 2017]的报道,2017年,全球每天创造出2.5个百万亿字节(quintillions)的数据,而根据[Sta, 2018]的预测,这个数字每年增长25%。在我们越来越注重数据的世界中,信息交换的增长促使需要更快的软件和更快的硬件。可以说,数据的增长不仅对计算能力有需求,还对存储和网络系统有需求。在PC时代[2],开发人员通常是直接在操作系统之上编写程序,可能会使用少量的库。随着世界向云时代转变,软件堆栈变得更加深入和复杂。大多翻译 2023-08-01 00:55:50 · 166 阅读 · 0 评论 -
Preface
但是,本书的范围不限于上述行业。上下文切换是指计算机在操作系统内核中,从一个线程或进程切换到另一个线程或进程时,保存并恢复相关的执行状态(即上下文)的过程。当一个进程或线程被切换出去时,系统必须保存当前进程或线程的执行状态,并加载并恢复下一个进程或线程的执行状态。这个过程可能会带来一定的开销,因为在保存和加载执行状态期间,CPU需要花费一些时间,而这段时间在执行程序时并没有为应用程序的运行做出贡献。总之,SIMD的原理就是减少CPU对内存的访问次数,尽可能多地利用处理器内部并行性,从而提高数据处理的效率。翻译 2023-07-31 22:37:09 · 127 阅读 · 0 评论