REP 指令是否被视为向量操作?

YAY*_*est 2 x86 assembly simd

我试图理解 SIMD 和向量指令的概念。如果我理解正确:

  • 向量指令是对一维数据数组(=向量)进行操作的指令,与对单个数据项进行操作的标量指令相反。
  • SIMD 指令实际上是单指令多数据指令,它们看起来与向量指令相同......我真的不知道有什么区别,如果有的话......

REP 指令对数据数组进行操作,因此看起来它们实际上是 SIMD/向量指令。我还没有看到任何文章将它们描述为向量指令,而且我知道 REP 指令不是 x86 的 SIMD 扩展的一部分。

我的问题是:

  1. REP 是否被视为向量操作?
  2. REP 是否被视为 SIMD 指令?
  3. 矢量和 SIMD 指令之间有什么实际区别吗?

对我的第三个问题的快速谷歌搜索让我想到了这个:

向量处理架构现在被认为与 SIMD 计算机是分开的,因为向量计算机通过流水线处理器一次一个单词处理向量(尽管仍然基于单个指令),而现代 SIMD 计算机处理向量的所有元素同时。

在我读过的实际文章中,我没有看到提到的差异,向量和 SIMD 术语可以互换使用,所以让我认为没有实际差异的原因是什么......

Joh*_*pin 5

“矢量”和“SIMD”的意思大致相同,但在常用用法中,这两个术语通常指向不同的实现方法。这种区别源于计算术语的历史。两个“载体”和“SIMD”指令集是基于对其中不存在数据相关性的情况下执行对多个数据元素相同的操作的概念的操作顺序。当没有数据依赖时,操作可以按任何顺序执行,包括同时执行。

从历史上看,“向量”是较旧的术语,“向量”指令被认为是单个指令,通过单个功能单元对操作进行流水线操作,从而对一系列元素执行某些操作。“单一功能单元”作为一个概念与矢量化无关——它是当晶体管非常昂贵时(1960 年代中期到 1990 年代中期)实现向量机的方式。最近的“向量”架构使用单个向量指令来跨多个功能单元进行流水线操作。例如,NEC SX-Aurora TSUBASA 处理器具有 256 个元素的向量寄存器和 32 个向量功能单元,每个 256 个元素的向量向每个向量功能单元发送 8 个元素。

我不知道“SIMD”这个词是什么时候第一次使用的,但我不记得在 1990 年代中期之前看到过它的普遍使用,当时“SIMD”指令最初是作为一种在较小的计算机上执行多个并行操作的手段而开发的。现有寄存器宽度内的数据大小。例如,Intel MMX 指令集 (1997) 使处理器能够对 64 位寄存器的内容执行独立的 8/16/32 位操作。后来的 SIMD 指令集(SSE 等)提供了比任何单一支持的数据类型都更宽的新寄存器,以允许对寄存器内高达 64 位宽的独立字段进行操作。指令集的设计支持跨整个 SIMD 寄存器宽度的操作的同时操作,但这不是必需的。例如,AMD 已经生产了几代处理器,这些处理器支持比功能单元的并行性更宽的 SIMD 寄存器上的指令。例如,AMD 的第一代 EPYC 处理器支持 256 位 SIMD 指令,但这些指令会在两个连续周期内分派到 128 位宽的功能单元。ARM 的可扩展向量扩展进一步分离了向量宽度和并行功能单元数量的概念。

x86 架构中的“REP”指令为“字符串指令”和“输入/输出”指令提供类似向量的功能的能力有限。它们不是通用机制,我相信许多英特尔处理器设计人员希望它们可以从指令集中删除。一些有趣的历史笔记在https://software.intel.com/en-us/forums/intel-fortran-compiler/topic/275765的论坛讨论中

  • 值得一提的是,尽管 `repe/ne scas/cmps` 实现了 memchr / memmem (即显式长度字符串搜索/比较),但它们在现代 CPU 上并不“高效”。就像每次重复 1 个周期一样,与简单的非 SIMD 循环相同。只有非条件 `rep movs/stos` memcpy / memset 操作具有使用宽加载/存储(与 SIMD 相同的功能单元)进行大量重复计数的微代码,并且仍然存在大量启动开销。不过,这对于内核代码来说非常好,因为内核代码如果不保存/恢复 SIMD 寄存器状态就无法使用 SIMD。 (2认同)
  • Patterson 的文章强调了可编程“向量长度”在静态和动态指令计数中的作用。RISC-V 向量扩展(和 ARM 可扩展向量扩展)将向量长度与功能单元的数量解耦(如上所述),而且还提供允许单个循环处理许多不同向量长度和对齐的功能。我将这些方法称为“传统”向量指令集和 SIMD 指令集之间的中间方法。 (2认同)