不同的 mmx、sse 和 avx 版本是互补的还是彼此的超集?

Are different mmx, sse and avx versions complementary or supersets of each other?

我想我应该熟悉 x86 SIMD 扩展。但在我开始之前,我 运行 遇到了麻烦。我找不到关于其中哪些仍然相关的很好的概述。

x86 架构几十年来积累了大量 math/multimedia 扩展:

新的是否是旧的的超集,反之亦然?或者它们是互补的?

其中一些已弃用吗?其中哪些仍然相关?我听说过 "legacy SSE".

其中有些是相互排斥的吗? IE。他们共享相同的硬件部件吗?

我应该一起使用哪个来最大限度地提高现代 Intel / AMD CPU 的硬件利用率?为了争论起见,让我们假设我可以找到这些说明的适当用途......如果没有别的,用 CPU 给我的房子供暖。

它们是互补的。

每个新指令集扩展都会添加新指令,并最终添加新的编程模型(例如新寄存器)。

None 已弃用,出于兼容性原因,弃用指令几乎是不可能的。然而,如果不是很广泛地传播,一些可选的扩展可能不存在或从较新的模型(如 AMD 的 FMA4)中删除。
虽然有些是退化的,但可以使用 FPU 和 MMX 完成的所有事情都可以使用 SSE+ 更有效地完成。

从可以使用一个或另一个的意义上说,它们并不互斥,毕竟它们是指令而不是操作模式(例如真实模式与保护模式)。
唯一可能的 "conflict" 是在 MMX 和 FPU 之间,因为它们共享同一组寄存器的低位部分,但具有不同的编程模型。
新的向量寄存器从128位增长到256位,再到512位,每次以前的寄存器都变成新寄存器的低位部分。

你可以一起使用它们,它们提供特定的硬件支持来实现简单的操作。

它们就像乐高积木,你只受限于你的想象力(或设计师的想象力)。


这里是这个指令集扩展的简单列表。
仅列出了部分功能,完整的参考资料请参阅第 9 至 14 章的Intel Manual Vol1

另请参阅 https://hjlebbink.github.io/x86doc/ 以获取英特尔第 2 卷(指令集参考)手册的 table 内容,以及向该手册条目添加指令的扩展列表。

  • MMX
    介绍八个 64 位寄存器 (MM0-MM7) 和使用八个 signed/unsigned 字节、四个 signed/unsigned 字、两个 signed/unsigned 双字的指令。

  • 3DNow!
    向 MMX 添加对单精度浮点操作数的支持。支持的运算很少,例如加法、减法、乘法。

  • 上海证券交易所
    介绍 eight/sixteen 128 位寄存器 (XMM0-XMM7/15) 和使用四个单精度浮点操作数的指令。也在 MMX 寄存器上添加整数操作。 (SSE 的 MMX 整数部分有时称为 MMXEXT,并在一些没有 xmm 寄存器和 SSE 的浮点部分的非英特尔 CPU 上实现。)

  • SSE2
    介绍了使用 2 个双精度浮点操作数和 128 位 xmm 寄存器中的压缩 byte/word/dword/qword 整数的指令。

  • SSE3
    添加一些不同的指令(主要是浮点),包括一种特殊的未对齐加载(lddqu),它在 Pentium 4 上更好,同步指令,水平 add/sub.

  • SSSE3
    同样是一组不同的指令,主要是整数。第一个从寄存器而不是硬编码 (pshufb) 获取其控制操作数的洗牌。更多水平处理、随机播放、packing/unpacking、字节上的 mul+add 和一些专门的整数 add/mul 东西。

  • SSE4 (SSE4.1, SSE4.2)
    添加大量指令:通过为所有整数数据类型(尤其是 32 位整数一直缺乏)提供 min 和 max 以及其他操作来填补大量空白,其中以前整数 min 仅适用于无符号字节和有符号 16 -少量。还有缩放、FP 舍入、混合、线性代数运算、文本处理、比较。也是读取视频内存或将其复制回主内存的非临时负载。 (以前只有 NT 商店可用。)

  • AESNI
    添加对加速 AES 对称 encryption/decryption.

  • 的支持
  • AVX 添加eight/sixteen 256位寄存器(YMM0-YMM7/15).
    支持所有以前的浮点数据类型。三个操作数指令。

  • FMA
    添加融合乘加和相关指令。

  • AVX2
    添加对整数数据类型的支持。

  • AVX512F
    添加eight/thirty-two个512位寄存器(ZMM0-ZMM7/31)和8个64位掩码寄存器(k0-k7)。将大多数先前指令提升为 512 位宽。 AVX512 的可选部分添加指数和倒数指令 (AVX512ER)、scatter/gather 预取 (AVX512PF)、分散冲突检测 (AVX512CD)、压缩、扩展。

  • IMCI(英特尔至强融核)
    用于第一代英特尔至强融核(骑士角)协处理器的 AVX512 的早期开发。

我最近更新了 SSE, AVX, and x86 (and SSE2, avx2) 的标签 wiki。他们涵盖了很多。 tl;dr 摘要:AVX 汇总了所有以前的 SSE 版本,并提供了这些指令的 3 操作数版本。还有大多数 FP (AVX) 和 int (AVX2) insns 的 256b 版本。

有关各种 SSE 版本的摘要,请参阅维基百科或 knm241 的更详细答案。

我们真的不认为这会使 SSE 过时。更像是,将 AVX 视为相同旧 SSE 指令的新版本和更好版本。它们仍在非 AVX 名称下的参考手册中(例如,PSHUFB,而不是 VPSHUFB。)您可以混合使用 AVX 和 SSE 代码,只要您使用 VZEROUPPER当需要避免将 VEX 与非 VEX insns 混合使用时出现性能问题(在 Intel 上)。因此,在处理您必须调用可能 运行 非 VEX SSE 指令的库,或者您的代码使用 SSE FP 数学但也有一些 AVX 代码为 运行 只有 CPU 支持它。

如果 CPU-兼容性不是问题,那么向量指令的遗留 SSE 版本将真正过时,就像现在的 MMX。 AVX/AVX2 至少在各个方面都稍微好一点,如果你把 VEX 编码的 128b 版本算作 AVX 的 insn,而不是 SSE。有时您仍会使用 128b 寄存器,因为您的数据只以大块的形式出现,但更常见的是使用 256b 寄存器一次对两倍的数据执行相同的操作。

SSE/AVX/x87-FP/integer 指令全部使用相同的执行端口。你无法通过混合它们来并行完成更多工作。 (Haswell 除外,其中 4 个 ALU 端口之一只能处理非向量 insns,如 GP reg 操作和分支)。