优化计算
在前一章中,我们讨论了如何为高效的内存访问扫清道路。一旦完成这一点,就是时候看看CPU如何处理它从内存中获取的数据了。现代应用程序需要大量的CPU计算,尤其是那些涉及复杂图形、人工智能、加密货币挖矿和大数据处理的应用程序。在本章中,我们将专注于优化计算,这可以减少CPU需要完成的工作量,并提高程序的整体性能。
当应用TMA方法时,低效的计算通常反映在Core Bound
类别中,以及在一定程度上反映在Retiring
类别中。Core Bound
类别代表了CPU乱序执行引擎内所有非内存问题引起的停顿。主要有两个类别:
- 软件指令之间的数据依赖性限制了性能。例如,一系列依赖操作可能导致指令级并行性(ILP)低下,浪费了许多执行槽。下一节将更详细地讨论数据依赖链。
- 硬件计算资源短缺(也称为执行吞吐量不足)。这表明某些执行单元过载(也称为执行端口竞争)。当工作负载频繁执行许多相同类型的指令时,可能会发生这种情况。例如,AI算法通常执行大量的乘法运算,科学应用程序可能运行许多除法和平方根运算。但在任何给定的CPU核心中,乘法器和除法器的数量都是有限的。因此,当端口竞争发生时,指令排队等待执行。这种性能瓶颈非常特定于特定的CPU微架构,通常没有解决办法。
在[@sec:TMA]中,我们说高Retiring
指标是代码表现良好的一个好指标。其背后的原因是执行没有停顿,CPU以高速度退役指令。然而,有时它可能掩盖了真正的性能问题,即计算效率低下。一个工作负载可能执行了大量过于简单的指令,并没有做很多有用的工作。在这种情况下,高Retiring
指标不会转化为高性能。
在本章中,我们将看看一些众所周知的技术,如函数内联、向量化和循环优化。这些代码转换旨在减少执行指令的总量,或者用更高效的指令替换它们。