Windows 处理器亲和性如何与超线程 CPU 协同工作?

Windows 处理器亲和性如何与超线程 CPU 协同工作?

Windows 处理器亲和性如何与超线程 CPU 配合使用?让我们使用一个具有四个内核的系统作为示例(如图所示),每个内核都有一个超线程虚拟内核。

  1. 下面的每个“CPU”对应哪些核心?
  2. 下面的 CPU 6 和 CPU 7 是否代表一个核心;HT 和真正的核心?
  3. 例如,如果 CPU 6 代表真实核心,而 CPU 7 代表 HT 核心,那么仅分配给 CPU7 的线程是否只会获得真实核心的剩余资源?(假设核心正在运行其他任务)
  4. 超线程是否完全在处理器内部管理,以便线程在内部进行处理?如果是这样,是在 CPU 范围还是核心范围?示例:如果 CPU 6 和 7 代表一个核心,那么将进程分配给哪个核心是否无关紧要,因为 CPU 会根据情况为正在运行的线程分配资源?
  5. 我注意到,至少根据任务管理器显示,长时间运行的单线程进程在核心之间来回切换。这是否意味着将进程分配给单个核心会稍微提高性能(通过避免上下文切换和缓存失效等)?如果是这样,我是否可以知道我没有分配给“只是一个虚拟核心”?

对我来说,这一切都非常模糊和令人困惑。HT 很棒,但它似乎确实降低了资源分配的透明度。

处理器亲和性菜单

答案1

下面的每个“CPU”对应哪些核心?

假设我们有核心 1、2、3 和 4,CPU4 和 CPU5 代表核心 3。

下面的 CPU 6 和 CPU 7 是否代表一个核心;HT 和真正的核心?

两者之间没有区别——它们都有到 CPU 的物理硬件接口,逻辑接口是用硬件实现的(参见英特尔酷睿处理器数据表,第 1 卷了解详情)。基本上,每个核心都有两个独立的执行单元,但它们之间共享一些公共资源。这就是为什么在某些情况下超线程实际上会降低性能。

例如,如果 CPU 6 代表真实核心,而 CPU 7 代表 HT 核心,那么仅分配给 CPU7 的线程是否只会获得真实核心的剩余资源?(假设核心正在运行其他任务)

参见上文。仅分配给 CPU6 或仅分配给 CPU7 的线程将以完全相同的速度执行(假设线程执行相同的工作,并且处理器中的其他核心处于空闲状态)。Windows 了解启用 HT 的处理器,进程调度程序会考虑这些因素。

超线程是否完全在处理器内部管理,以便线程在内部进行处理?如果是这样,是在 CPU 范围还是核心范围?示例:如果 CPU 6 和 7 代表一个核心,那么将进程分配给哪个核心是否无关紧要,因为 CPU 会根据正在运行的线程分配适当的资源?

两者都有。实际的硬件本身不是调度在哪些核心上运行程序,这是操作系统的工作。然而,CPU 本身负责在实际执行单元之间共享资源,英特尔规定了如何编写代码以使此过程尽可能高效。

我注意到,至少根据任务管理器显示,长时间运行的单线程进程在核心之间来回切换。这是否意味着将进程分配给单个核心会稍微提高性能(通过避免上下文切换和缓存失效等)?如果是这样,我是否可以知道我没有分配给“只是一个虚拟核心”?

这是正常的行为,不,将它分配给单个核心将不是提高性能。话虽如此,如果出于某种原因您想确保单个进程仅在单个物理核心上执行,请将其分配给任何单个逻辑处理器。

进程“反复”的原因在于进程调度程序。这是正常现象,通过限制进程可以在哪些核心上执行(无论有多少线程),您很可能会遇到性能下降的情况,因为进程调度程序现在必须更加努力地工作,才能让所有事情都按照您施加的限制运行。是的,在大多数情况下,这种惩罚可能微不足道,但最重要的是除非你有理由这么做,否则不要

答案2

CPU 布局应该这样组织,以便无法识别所有 CPU 的操作系统获得最大性能。这意味着每个物理核心的一个虚拟核心将先列出,然后是任何物理核心的第二个虚拟核心。

例如,假设您有四个超线程核心,分别称为 A、B、C 和 D。如果假设 A 和 B 共享一个 L2 缓存,而 C 和 D 共享一个 L2 缓存,则顺序应如下:
0=A1 1=C1 2=B1 3=D1 4=A2 5=C2 6=B2 7=D2

这样,只占用两个 CPU 的操作系统就可以使用所有 L2 缓存。同样,只占用四个 CPU 的操作系统就可以使用所有执行单元。

再说一遍,事情本来就该如此。

当然,如果您使用的操作系统能够理解您的 CPU 拓扑,那就没关系了。BIOS 会填写一个表格,说明哪些核心共享执行单元、哪些核心共享缓存等等。您可能使用的每个完全支持您的 CPU 的现代操作系统都了解完整的 CPU 拓扑。

答案3

  1. 它们如何对应取决于您的 CPU 和主板如何枚举和识别核心。应该发生的是,首先枚举物理插槽,然后是逻辑核心,最后是虚拟核心。在您的例子中,核心 0-3 应该是物理核心,而 4-7 应该是虚拟 HT 核心。这样做的主要原因是,如果您运行的操作系统无法处理所有可用的执行单元,则最有可能先获得最独立的单元,然后再获得共享单元。如果假设的仅 2-CPU 操作系统在您的系统中找到 HT 对而不是 2 个不同的核心,那就不好了。(在内核调度程序可以为新 CPU 更新之前,这对于一些早期的 HT 系统来说是一个真正的问题。)
  2. 否。请参阅 1。
  3. 不。HT 比这更复杂。请记住,两个虚拟核心通常共享一些资源,而其他部分则分开,但一次只能执行其中一个。
  4. 有点。您的示例(假设)通常是正确的。但是,如果应用程序可以知道其运行的工作负载类型,它可以帮助操作系统适当地调度线程。
  5. 核心跳跃有一个非常好的理由:分散热工作负载。鉴于在许多情况下,所有核心共享更高级别的缓存(L2、L3),核心跳跃不会对性能产生重大影响,但热影响将很大,因为您不会在一个核心上出现“热点”,而其他核心则处于空闲状态。现在,在多插槽系统(特别是 NUMA 系统)中跨插槽可能会对性能产生重大影响。不过,大多数调度程序都意识到了这一点,并考虑到了这一点。

最终,这可以归结为,除了确保您运行的是了解系统中各个位的最新操作系统之外,您(作为最终用户)通常无法通过线程亲和性来显著影响性能。

如果发现手动分配亲和力对任何工作负载有重大影响,请将其作为错误报告给应用程序开发人员,以便程序能够得到修复。

相关内容