超线程对编译器性能的影响?

23

假设我们想要尽快编译一个大项目(例如GCC或Linux内核),启用超线程功能的CPU(例如Intel Core i7)是否会在启用或禁用超线程时更快地运行编译器?是否有发表过测试这一点的基准测试数据?

我对超线程的理解是,每个核心可以从两个(或多个)进程中选择指令。通常情况下,这使得核心更有效率,因为功能单元更不可能处于空闲状态。但是,也存在性能损失的潜在可能性,因为在同一核心上运行的进程共享缓存等资源,并且可能会互相干扰。实际上是否提高了性能取决于工作负载。

那么,在编译器工作负载下,性能是否提高了呢?如果是,提高了多少?


我最近没有相关经验,但编译不是倾向于受到I/O限制吗? - Ken
玩一下“make -j N”,并测量不同N的系统资源? - Nikolai Fetissov
@Nikolai,如果我有一台超线程CPU可以玩耍的话,我会这样做的。我问这个问题是为了知道是否值得购买一台。 - Jay Conrod
6
@Ken,我的经验与你相反。由于我通常会频繁进行小的更改并重新编译,因此所有源代码通常都在磁盘缓存中。当编译时,我经常看到CPU使用率达到100%。 - Jay Conrod
2个回答

28

在 Ubuntu 8.04 x86 上编译 coreutils-8.4

使用启用了 HT 的 Intel Atom 1.6 GHz:

~/coreutils-8.4$ make clean > /dev/null
~/coreutils-8.4$ time make > /dev/null

real    2m33.375s
user    2m22.873s
sys     0m10.541s
~/coreutils-8.4$ make clean > /dev/null
~/coreutils-8.4$ time make -j2 > /dev/null

real    1m54.707s
user    3m26.121s
sys     0m13.821s
~/coreutils-8.4$ make clean > /dev/null
~/coreutils-8.4$ time make > /dev/null

real    2m33.372s
user    2m22.753s
sys     0m10.657s
~/coreutils-8.4$ make clean > /dev/null
~/coreutils-8.4$ time make -j2 > /dev/null

real    1m54.851s
user    3m26.145s
sys     0m13.685s
~/coreutils-8.4$

因此,超线程可以将运行时间缩短到75%,相当于增加33%的处理能力(我运行了两次以确保所有内容都在内存缓存中)。

以下是一项对照实验,展示了仅使用make -j2不能提高在Ubuntu 8.04 x86上编译coreutils-8.4的速度。

单核 Core 2 Quad 2.5 GHz VM(无超线程):

~/coreutils-8.4$ make clean > /dev/null
~/coreutils-8.4$ time make > /dev/null

real    0m44.453s
user    0m38.870s
sys     0m5.500s
~/coreutils-8.4$ make clean > /dev/null
~/coreutils-8.4$ time make -j2 > /dev/null

real    0m45.131s
user    0m40.450s
sys     0m4.580s
~/coreutils-8.4$ make clean > /dev/null
~/coreutils-8.4$ time make > /dev/null

real    0m44.621s
user    0m39.090s
sys     0m5.340s
~/coreutils-8.4$ make clean > /dev/null
~/coreutils-8.4$ time make -j2 > /dev/null

real    0m45.165s
user    0m40.390s
sys     0m4.610s
~/coreutils-8.4$

这太棒了。对照实验表明这确实有所不同。谢谢。 - Jay Conrod
2
我希望在禁用超线程的情况下,能够看到Atom上的测量结果重复显示,如果可能的话。此外,关于内存使用的说明也很好,因为Atom可能会开始交换或丢弃缓存,特别是在-j2的情况下。 - Eroen
与 Nehalem 或 Sandybridge 型号的 CPU 或 AMD Ryzen 相比,In-order Atom 利用指令级并行性方面表现不佳。HT 对 Atom 的帮助可能比对主流 CPU 更多。或者它可能会帮助更少,因为主流 CPU 有更大的缓存和更多的执行资源(以及更高的分支预测错误惩罚,而 HT 允许另一个线程在一个线程从误判中恢复时使用 CPU)。因此,在主流 CPU 上,HT 可能也会显著地帮助,但比例可能会相当不同。 - Peter Cordes
1
我会对这个实验持保留态度。通常一个单进程的构建过程会像是读取、处理、写入或者io/cpu/io,但是通过使用两个线程来进行Make构建,你可以改善这种情况。可以尝试从BIOS中禁用超线程并进行测试。 - auselen
@auselen 这是一个高度简化的实验,有很多限制,但控制实验特别针对您的关注点。 - netvope
https://www.phoronix.com/review/amd-epyc-9754-smt 在一台搭载128个Zen4c核心的AMD Bergamo上测试了SMT开/关。使用clang和GCC编译时,启用SMT与禁用SMT相比,编译时间更长。(由于有足够的内存,并且源代码已经热缓存在磁盘缓存中,并且在无SMT构建中已经有足够的并行性,因为这是一个庞大的物理核心数量。) - Peter Cordes

0

这完全取决于编译器是否编写为多线程。如果是的话,超线程肯定会加速一些操作,因为操作系统可以将编译器线程的不同部分调度到不同的核心上。我同意Ken的观点,编译通常更受I/O限制而不是处理强度,因此拥有快速的硬盘比拥有100个核心的快速处理器更为必要。


如果编译器通过make -j N(N表示逻辑处理器数量)被调用,会怎么样呢?我担心由于独立的编译器进程不共享任何数据,它们实际上可能会降低性能。 - Jay Conrod
4
  1. 在Linux系统上,只要具备足够的物理内存,编译过程总是可以避免I/O瓶颈的问题。
  2. 流行的构建系统可以并行调用多个编译器进程,使得多线程编译器不再是问题。(尽管链接器相对来说仍然存在一些问题)
- Eroen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接