【问题标题】:Multithreaded(Hyperthreading) v/s multicore processors多线程(超线程)与多核处理器
【发布时间】:2014-01-23 04:52:56
【问题描述】:

我正在我的大学学习并行计算课程,显然我们需要了解程序员级别的架构。谁能说出开发多核处理器的动机是什么?为什么多线程处理器不够用?为什么我们需要将管道分布在多个核心上,而不是将它们放在一个大核心上?

【问题讨论】:

    标签: multicore computer-architecture hyperthreading


    【解决方案1】:

    随着 CPU 变得越来越小,速度越来越快,它们接近了几个物理极限,这使得在当前路径上继续运行的成本更高:

    • 当今的 CPU (intel) 采用 22 nm(AMD 在 32 nm)技术制造,大致相当于 90 个硅原子直径。理论上的限制应该是一个原子直径,但实际上你需要的远不止这个。有多少?
    • 电的速度。假设速度为光速的 2/3,我们发现在 2 GHz CPU 上,电流将在一个时钟周期内传播 10 厘米(约 4 英寸)。如果要做一些有价值的事情——例如执行加法或类似操作——它需要通过一个执行加法的互连设备系统,并且这些设备必须能够在一个周期的一小部分(0.5 纳秒)内切换状态)。它们的切换速度有多快?
    • 驱动 CPU 的频率越高,消耗的功率就越多。消耗的功率越多,产生的热量就越多。产生的热量越多,需要的冷却就越多,否则 CPU 会在运行过程中熔化。 AMD 最新的 FX 处理器消耗 220W 的功率 - 超过两个 100 瓦的灯泡 - 并以 4.7 甚至 5 GHz 的速度运行。 “应该”冷却系统比 CPU 本身更贵吗?在发烧友系统中,有时会出现这种情况,但在主流系统中则不然——购买它们的成本太高了。

    这就是 CPU 制造商转向多核的原因。理论上,四个核心的处理能力是一个核心的四倍。一些应用程序可以实现这一点,但大多数不会。随着时间的推移——也许——越来越多的应用程序可以更好地利用多核。

    在任何时候,构成 CPU 的大多数组件都没有被使用,理论上可用于处理。这就是超线程存在的理由。两个不同的执行线程可以并行运行,只要它们不需要同时访问同一个组件。但他们经常这样做。然后一个必须停下来等待另一个。

    另辟蹊径:可以在芯片上实现的必要功能将始终比在其他地方实现更快的执行速度。外部存储器将始终以 CPU 内部速度的一小部分执行。 80286在CPU芯片上集成了内存保护和虚拟内存。这使得它比在芯片外实现功能的竞争设计要快得多。尽管 80386 芯片组的变体实现了片外高速缓存,但 80486 具有片上 L1 高速缓存。然后是片上 2 级 (L2) 和后来的 L3 缓存。 Pentium 有一个宽两倍的外部存储器接口,可以在同一时间跨度内读取两倍的数据。后来出现了两个或更多的外部存储器接口。后来,外部存储器的控制器被移到芯片上,以减少对正常操作的干扰。每次访问时,内存芯片可以提供两倍 (DDR)、四倍 (DDR2) 或八倍 (DDR3) 的数据。 DDR4 正在开发中。可以看出,实际 CPU 和外部存储器之间的接口变得越来越复杂,才能勉强获得那一点额外的性能。实施的解决方案基于最适合通用情况的常见访问场景,以便标准软件运行得更快一点。专业软件试图更有效地使用界面,并可以实现惊人的性能。大多数其他软件永远不会接近。相当多的混乱应用程序甚至会超出正常的访问模式并变得更慢,因为它们与界面不符。

    如果您退后一步,您会意识到“最佳”解决方案是在 CPU 和外部存储器之间建立一条直接的、最简单的路径。曾经有一台标准计算机可以做到这一点 - 基于 80386 的 Compaq Deskpro 386/20 - 它使用静态 RAM (SRAM) 而不是现在每个人都使用的动态 RAM (DRAM)(因为它的价格要便宜得多内存单位)。 SRAM 能够与 CPU 保持同步,而 CPU 在多周期指令期间实际上会更慢。

    我的意思是说,许多因素会影响整体硬件性能,因此说“CPU 性能”可能意味着很多事情。他们都一起工作,并经常合作以取得更好的业绩。有时他们会做相反的事情。

    当同时访问相同的资源时,超线程会发生冲突。此类资源不限于 CPU 中的功能组件。超线程共享相同的缓存和内存接口,也会在那里发生冲突。非超线程多核也会发生冲突,但这会发生在它们访问公共资源时,这通常意味着 L3 缓存和内存接口。只要它们停留在专属于它们的资源(核心、L1 和 L2)内,它们就可以不间断地运行。

    主存储器可以最大速率传送数据。在一个标准的、优化不佳的应用程序中,它通常以 100% 的速率工作。如果可以将 100% 平均分配给可用的 n 个内核,则最佳状态是。

    设计良好的硬件解决方案将比其他解决方案更快地处理。通过将硬件设计考虑在内,旨在提高运行效率的软件将胜过普通软件。

    一个有点复杂的答案,但这是一个复杂的主题:-)

    【讨论】:

    • 我严重怀疑任何普通 PC 使用 SRAM(静态 RAM)作为主存储器;您可能正在考虑 SDRAM(同步动态 RAM)。
    • 我认为你错过了一些东西。 SDRAM 出现的时间并不长。我相信这是 DDR 之前的 DRAM 一代。那将是九十年代后半期。 DeskPro 386 是八十年代后半期。这是 memory4less.com 的链接以及他们关于升级 DeskPro 386 memory4less.com/confitems.aspx?modelid=80008453 的说明。它声明“主内存板上的 36 个 SRAM 插槽”。在那些日子里,额外的内存是逐个芯片安装的。 DeskPro 386/16 在当时非常罕见。
    • 好吧,后来 SDRAM 变得很普遍。 Deskpro 386 使用的是静态列 RAM(由 this support document 表示)。这实际上是 Fast Page DRAM not Static RAM 的变体。 This page 表示混淆并不少见(混淆似乎很容易理解)。 (找到这类资料并不容易,我只找到了一份文件。)
    • @Paul A. Clayton:您确定该文档涉及原始的 DeskPro 386/16 (1986)?此后不久,英特尔推出了具有高速缓存功能的芯片组,从而消除了对全 SRAM 主存储器的需求。此外,原来的 386/16 只允许 80287 的速度远低于 8MHz。
    • 看起来你可能是对的,但这是一个短暂的设计决定。 David Hess posted on Real World Technologies 确认使用 SRAM。 (可悲的是,这个评论线程没有为答案添加任何内容,但 很有趣。)
    【解决方案2】:

    多线程处理器实际上不能同时执行代码。他们唯一要做的就是虚拟化处理器,使操作系统看起来像两个物理内核,这有一点速度优势。

    没有超线程的单核处理器有时可能会浪费时间等待指令完成,因为它需要获取数据,或者它有缓存未命中或者可能是错误的分支预测。虽然乱序执行可以解决其中的一些问题,但添加另一个线程可以接管并使用 CPU 资源一段时间,而另一个线程被阻塞可以提高性能。

    但是,这个带有超线程的单核仍然只有一个 FPU、一个 ALU、一个控制单元、一个内存接口等。由于这个限制,真正的并发线程执行需要复制这些组件。复制内核并指定它们之间的接口比尝试平衡多个 ALU 或 FPU 的设计要简单得多,单个内核中有多个线程。

    【讨论】:

    • 其实这很不准确。如果您查看Hyperthreading,您会发现它们确实为每个线程复制了寄存器和程序计数器。多线程处理器实际上确实维护了两个独立的执行线程,它们只共享计算硬件(ALU、FPU 等)。他们肯定不使用循环上下文切换;他们使用对方目前未使用的硬件。例如,一个线程可能会继续执行,而另一个线程正在等待内存获取。
    • @mebob 我明白你的意思是我的理解不正确。我试图解决这个问题。随意编辑澄清,我把它变成了一个社区维基。或者,提供您自己的答案。
    【解决方案3】:

    增加单个内核的宽度会在硅面积和功耗方面产生几何成本。

    制作大小合理的内核的多个副本具有线性成本(+ 互连/一致性的开销很小)。

    制造一个超宽 CPU 只是为了用 SMT(又名超线程)将它切碎是很疯狂的。如果您需要出色的单线程性能,您会这样做,并且可以以某种方式冷却芯片,使其以接近更窄设计可以管理的时钟速度运行。 (你不能。)

    大多数代码中没有足够的指令级并行性来提供足够大的改进来证明更广泛的设计是合理的。您在 IPC 中获得的任何东西(每个时钟的 insns)都会在时钟速度上有所损失,因为您无法在不过热的情况下快速运行它。

    例如,20 年来,英特尔已从 3 宽问题宽度(PPro 中的原始 P6 到 Pentium-M)发展到 4 宽问题宽度(Core2 到 Skylake)。 x86 难以解码,但带有 uop-cache 的 SnB 系列设计很容易拥有比解码器吞吐量更宽的 OOO 管道。

    增长更多的是执行端口的数量,以及每个端口上执行单元的数量。在最近的英特尔设计中,相同的指令可以在不同的数据上并行运行。例如Haswell 和更高版本可以在每个时钟执行两个 FP 乘法。 IvB 和更早的版本只有一个 FP mul 每个时钟的吞吐量,因为只有一个 FP mul 执行单元(在 port1 上)。

    较旧的设计(如 PIII)只有两个 ALU 执行端口,因此他们可以管理的每个时钟的三个指令中的一个必须是内存操作(加载或存储)。 Haswell 有四个 ALU 端口(其中三个可以处理向量指令)。因此,无论指令的组合如何,最新的 CPU 都很有可能并行执行很多任务。

    拥有大量芯片区域但很多时候不做任何事情的“低效率”不是问题。真正的限制因素是功率,而不是死区。这就是为什么现代 CPU 可以拥有如此多的无法一次使用的执行能力。


    请注意,如果超线程可以使 HT 在内核之间共享的执行资源饱和,那么它实际上会减慢您的代码速度。或者更糟糕的是,如果来自竞争性共享 L1/L2 缓存的额外缓存压力导致每个线程中出现更多的缓存未命中。

    当一个或两个线程在给自己一个完整的内核时实现低指令/时钟 (IPC) 时,HT 是一个巨大的胜利。隐藏内存延迟的两个乱序窗口很好,对于分支错误预测非常有用。

    对于在不同执行单元上出现瓶颈的两个线程来说,这是一个小小的胜利。 (例如,端口 5 上的 shuffle 单元与端口 0/1 上的 add/mul)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-12-29
      • 2020-02-26
      • 2021-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-17
      相关资源
      最近更新 更多