11

极术小姐姐 · 10月22日

一文解谜 SMT 系统上 CPU 使用率的盲点

image.png

Arm Neoverse N 系列和 V 系列处理器并未采用同步多线程 (SMT) 技术。在 Arm Neoverse 处理器上运行时,每个线程始终能够访问处理器的全部资源。这有助于提高在云环境中执行的可预测性,确保每个线程都能完全访问处理器资源,并提供更强大的保护,防止线程之间发生意外数据泄露。

在采用 SMT 技术的处理器中,每个物理处理器分为两个或两个以上的逻辑核心。这些逻辑核心相互共享一些资源。例如,一种常见的设计是,逻辑核心共享执行单元,分支预测器、预取器和缓存等处理器结构。在 SMT 系统中,每个逻辑核心都有自己的寄存器和程序计数器,因此每个逻辑核心能够执行独立的执行线程。市面上典型的 SMT 实现方案包括英特尔的超线程 (Hyper-Threading) 和 AMD 的 SMT。

如果比较 Neoverse 处理器和其他支持 SMT 的处理器的 CPU 使用率,有时会出现这样的情况:在类似的轻负载水平下,Arm CPU 使用率似乎更高。这可能令使用者认为 Arm 平台的性能可用扩展空间较小。在本文中,我们将探讨轻负载场景下,比较采用 SMT 和未采用 SMT 的系统时,为什么“CPU 使用率”指标可能具有误导性。

测量 CPU 使用率

Linux 操作系统根据 CPU 核心在工作还是处于空闲状态来计算 CPU 使用率。SMT 模式下的逻辑核心共享物理核心的执行资源。在轻负载场景下,逻辑核心能够以物理核心的能力全速运行。因此,操作系统可能会显示逻辑 CPU 使用率低。但这并不意味着物理核心负载低,因为两个逻辑核心的负载都添加到了物理核心中。

这就导致负载较轻的情况下 SMT 系统与未采用 SMT 的系统相比,似乎有更多的剩余性能空间。但其实这可能是一个误导。例如以下这个经过大幅简化的场景:

  • 两个逻辑核心 LCore0 和 LCore1 在一个物理处理器上运行。
  • 每个逻辑核心都运行一个处理 Web 请求的工作负载。每个请求需使用整个 CPU 0.1 秒进行处理,然后返回等待状态。
  • 在一秒的时间范围内,LCore0 和 LCore1 分别为三个请求提供服务。
  • LCore0 的执行时间为 0.3 秒,空闲时间为 0.7 秒,因此计算得出 CPU 使用率为 30%。
  • LCore1 也是如此,同样计算得出 CPU 使用率为 30%。
  • 二者相加,物理处理器被充分使用的时间为 0.6 秒,因此实际使用率为 60%。

image.png
图 1:SMT 下的 CPU 使用率说明

分析上述示例中的逻辑核心使用率时,使用者可能会推断 CPU 的能力足以继续处理 14 个 Web 请求。然而,实际 CPU 只能够再处理四个请求。

需注意的是,与实际工作负载相比,上述示例经过简化,实际工作负载的物理处理器使用率可能更低,具体取决于支持在逻辑核心之间共享物理处理器资源的动态条件。在尝试预估系统上可能有多少可用性能空间时,这种不可预测性会是一项挑战。

在本文中,我们将设计一个微型基准测试,以及使用实际工作负载在 SMT 系统上演示此行为。

微型基准测试

这个微型基准测试包含了大量读数据和一些简单数学运算。它会产生较大的 IPC,从而充分利用物理处理器的可用执行单元。为了模拟不同的负载水平,我们在计算循环中添加了不同的休眠时间。一级负载最轻,七级负载最重。在支持 SMT 的系统上,我们先在一个逻辑核心上运行程序,然后在同一物理处理器的两个逻辑核心上同时运行程序。对从轻到重的所有负载水平都做同样的测试。对于非 SMT 系统,我们使用 Neoverse N2 进行测试。对于双核测试情形,我们使用连接到同一 Arm CMN 交叉点的两个核。需注意的是,我们在编译时禁用了向量化,因为实际工作负载中的大多数代码不像该微型基准测试那样容易实现向量化。

运行测试

我们在运行频率为 3.5GHz 的主流 SMT 系统和未采用 SMT 的基于 Neoverse N2 的平台 (2.7GHz) 上运行微型基准测试。

SMT

在我们的系统中,逻辑核心 0 和逻辑核心 32 共享同一个物理核心。因此,我们将在核心 0 和核心 32 上运行。

image.png

此处列举了在两个核心上同时运行微型基准测试的输出示例。1000000000 是我们使用微型基准测试进行的计算轮数。7 是我们希望达到的负载级别。我们将使用 perf 工具来收集 time elapsed(即总运行时间)和 insn per cycle(即 IPC)。CPU 使用率通过 top 命令获取。

image.png

收集到的结果如下所示:

image.png

从数据中可以看出,从三级和四级负载开始,LCore 0 和 LCore 1 的综合 CPU 使用率逐渐超过 100%,相应地,两个核心的 IPC 大幅下降。

非 SMT

在 Neoverse N2 平台上,每个核心都是独立的物理核心。我们将在核心 0 和核心 1 上运行。

image.png

结果表明,在 Neoverse 系统上,两个核心的 IPC 与一个核心的 IPC 没有太大的差别。而且,从轻负载到重负载,IPC 没有下降。这一点与 SMT 系统截然不同。这意味着无论 CPU 使用率如何,CPU 的能力始终保持一致。

image.png

对结果的进一步分析

两个硬件线程影响

要想找到一个可靠的直接指标来判断物理核心的繁忙程度,这并非易事,但我们可以从其他角度进行判断。在这里,我们选择 IPC 进行分析。我们使用两个核心运行得到的数据除以一个核心运行得到的数据。这可以揭示 SMT 系统的特点。

image.png

在下图中,我们看到在轻负载的情况下,对于 SMT 系统,两个核心和一个核心的 IPC 几乎相同。这是因为物理核心并不繁忙,逻辑核心的所有操作几乎都是以物理核心的最快速度运行,因此 IPC 非常高。CPU 使用率看起来很低。但物理核心实际运行的负载是一个逻辑核的两倍。因此,物理 CPU 的使用率应该增加一倍。随着负载的增加,与一个核心相比,两个核心的 IPC 大幅降低。这是因为它们需要争用和共享执行单元中的资源。此时物理核心已经满载,无法像轻负载情况下那样及时处理来自两个核心的所有请求。最后,IPC 降至几乎一半。这证明两个逻辑核心正在共享物理核心。

相比之下,Neoverse 系统始终保持在 1,因为两个核心是独立的,无论负载水平如何,它们始终以相同的速度运行。

image.png
图 2:微型基准测试 IPC 比较

性能与 CPU 使用率的对比

在这里,我们将性能定义为“1000000000/总运行时间”。1000000000 是我们使用微型基准工具进行的测试轮数。由于我们使用的 Neoverse N2 平台的频率 (2.7Ghz) 远低于 SMT 系统 (3.5Ghz),因此我们将 Neoverse N2 平台的性能数据按比例调整为相同的 3.5Ghz。我们针对两个核心的情况进行对比,因为在生产环境中,同时使用物理核心的两个逻辑核心是最通常的用例。

image.png

下图展示了频率调整后的性能与 CPU 使用率。可以看到,随着 CPU 使用率的增加,SMT 系统的性能输出变得平缓。与此同时,Arm 的性能输出保持理想的线性增长趋势,并最终在高 CPU 使用率区域性能超过了 SMT 系统。因此,如果仅使用低 CPU 使用率区域的性能输出来预测 SMT 系统在高 CPU 使用率场景下的性能,可能会得到错误的结果。

image.png
图 3:微型基准测试调整后的性能

在这里,我们又创建了“性能达成率”指标,即“性能/CPU 使用率”。性能数据来自上表。处理工作负载时,理想的系统应保持恒定的比率,即特定的 CPU 使用率应提供特定的性能输出。

从该图中可以看出,随着 CPU 使用率的增加,SMT 系统的性能达成率大幅下降。而在 Arm 平台上,性能达成率表现得更好且恒定。

image.png
图 4:微型基准测试调整后的性能达成率

实际工作负载

下面试着用大家熟悉的工作负载来描述这个问题。在这里,我使用了 Flink 以及用于对 Flink 进行基准测试的 Nexmark。

测试说明

针对 SMT 系统和未采用 SMT 的基于 Neoverse N2 的系统,我们创建了两个具有类似硬件资源的集群。软件版本和配置也相同。

image.png

Nexmark 有多个测试用例,这里我们选择 Q0 测试进行比较。其他的测试也会有类似输出。

测试结果

Nexmark Q0 测试结果如下所示。对于 SMT 系统和 Arm 平台,在相同负载水平 (TPS) 下,从 top 工具中得到的 CPU 使用率不同。

image.png

可以看到,当工作负载水平较低时,Arm CPU 使用率高于 SMT 系统,但当 CPU 使用率达到大约 50% 后,SMT 系统的 CPU 使用率增长得更快。最后,我们看到在高 CPU 负载下,SMT 系统 CPU 使用率远高于 Arm 平台。当 CPU 得到充分使用时,Arm 平台可输出更高的 TPS。

image.png
图 5:不同 TPS 下的 Flink CPU 使用率

我们也可以从另一个角度来看:在相同的 CPU 使用率水平下,系统能够生成的 TPS 数量的趋势。起先,Arm 平台表现得并不突出,但当 CPU 使用率达到大约 50% 后,Arm 的性能大幅提高。

image.png
图 6:不同 CPU 使用率下的 Flink TPS

在这里,我们也创建了“性能达成率”指标,即 TPS/CPU_Usage。处理工作负载时,理想的系统应保持恒定的比率。从该图中可以看出,随着 CPU 使用率的增加,SMT 系统的性能达成率大幅下降。而在 Arm 平台上,性能达成率表现得更好。

image.png
图 7:Flink 性能达成率

因此,该 Flink 测试用例展示的结果与我们在微型基准测试中看到的结果相似。在轻负载场景下,Arm 平台可能会显示较高的 CPU 使用率。然而,超过某个点后,SMT 系统的 CPU 使用率会迅速超过 Arm,因此在高 CPU 使用率的情况下,SMT 系统的性能输出下降。

结论

在轻负载场景下,支持 SMT 的系统的 CPU 使用率可能会被低估。在预估还有多少额外性能空间可供我们在机器上部署工作负载时,CPU 使用率指标可能具有误导性。因此,在部署工作负载时,我们应在 CPU 被 100% 使用的情况下测试性能输出水平,然后根据得到的值留出性能缓冲区,而不是简单的根据 CPU 使用率预留性能空间。

END

作者:安谋科技 (Arm China) 主任软件工程师 常瑞
文章来源:Arm社区

推荐阅读

欢迎大家点赞留言,更多Arm技术文章动态请关注极术社区Arm技术专栏欢迎添加极术小姐姐微信(id:aijishu20)加入技术交流群,请备注研究方向。

推荐阅读
关注数
23582
内容数
1033
Arm相关的技术博客,提供最新Arm技术干货,欢迎关注
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息