CPI 和 IPC

这两个是两个基本指标,分别代表:

  • 每条指令周期数 (CPI) - 平均执行一条指令所需的周期数。

IPC=INST_RETIRED.ANYCPU_CLK_UNHALTED.THREAD, IPC = \frac{INST\_RETIRED.ANY}{CPU\_CLK\_UNHALTED.THREAD},

其中,INST_RETIRED.ANY 计算已完成指令的数量,CPU_CLK_UNHALTED.THREAD 计算线程不在中止状态时的核心周期数。

  • 每周期指令数 (IPC) - 平均每个周期完成的指令数。

CPI=1IPC CPI = \frac{1}{IPC}

使用哪一个取决于个人喜好。本书的主要作者更喜欢使用 IPC,因为它更容易比较。使用 IPC,我们希望每个周期尽可能多地执行指令,因此 IPC 越高越好。使用 CPI 则相反:我们希望每个指令的周期越少越好,所以 CPI 越低越好。使用“越高越好”的指标进行比较更简单,因为您不必每次都进行心理反转。在本书的其余部分,我们将主要使用 IPC,但再次申明,使用 CPI 也没有错。

IPC 和 CPU 时钟频率之间的关系非常有趣。从广义上讲,性能 = 工作 / 时间,我们可以将工作表示为指令数,时间表示为秒。程序运行的秒数是 总周期 / 频率

=×=IPC× \text{性能} = \frac{\text{指令} \times \text{频率}}{\text{周期}} = IPC \times \text{频率}

正如我们看到的,性能与 IPC 和频率成正比。如果我们增加这两个指标中的任何一个,程序的性能就会提高。

从基准测试的角度来看,IPC 和频率是两个独立的指标。我们见过许多工程师错误地将它们混为一谈,认为如果增加频率,IPC 也会上升。但事实并非如此,IPC 将保持不变。如果您将处理器的时钟设置为 1 GHz 而不是 5Ghz,您仍然会拥有相同的 IPC。这非常令人困惑,尤其是因为 IPC 与 CPU 时钟密切相关。频率只告诉单个时钟的快慢,而 IPC 不考虑时钟变化的速度,它计算每个周期完成的工作量。因此,从基准测试的角度来看,IPC 完全取决于处理器的设计,与频率无关。乱序内核通常具有比顺序内核更高的 IPC。当您增加 CPU 缓存的大小或改进分支预测时,IPC 通常会上升。

现在,如果您问硬件架构师,他们肯定会告诉您 IPC 和频率之间存在依赖关系。从 CPU 设计的角度来看,您可以故意降低处理器时钟频率,这将使每个周期更长,并且可以在每个周期中塞入更多工作。最终,您将获得更高的 IPC 但更低的频率。硬件供应商以不同的方式处理性能公式。例如,英特尔和 AMD 芯片通常具有非常高的频率,最近的英特尔 13900KS 处理器开箱即用即可提供 6Ghz 的睿频频率,无需超频。另一方面,Apple M1/M2 芯片的频率较低,但通过更高的 IPC 进行补偿。较低的频率有助于降低功耗。另一方面,更高的 IPC 通常需要更复杂的设计、更多的晶体管和更大的芯片尺寸。我们这里不会讨论所有设计权衡,因为这涉及另一个主题。我们将在 [@sec:secTrendsInPerf] 中讨论 IPC 和频率的未来发展。

IPC 对于评估硬件和软件效率都非常有用。硬件工程师使用此指标比较不同供应商的不同 CPU 代和 CPU。由于 IPC 是衡量微架构性能优劣的指标,因此工程师和媒体会使用它来表达最新 CPU 比上一代性能的提升。但要进行公平的比较,您需要在相同频率下运行这两个系统。

IPC 也是评估软件的有用指标。它可以让您直观地了解应用程序中的指令如何快速地穿过 CPU 管道。稍后,您将在本章中看到几个具有不同 IPC 的生产应用程序。内存密集型应用程序通常以低 IPC (0-1) 为特征,而计算密集型工作负载往往具有高 IPC (4-6)。

Linux perf 用户可以通过运行以下命令测量其工作负载的 IPC:

$ perf stat -e cycles,instructions -- a.exe
2369632 cycles
1725916 instructions # 0,73 insn per cycle
# 或更简单地:
$ perf stat ./a.exe

results matching ""

    No results matching ""