向量体系结构介绍
什么是向量?
在计算机体系结构,"向量"(vector)是指一个由多个相同类型且逻辑上相关的数据元素组成的有序集合。这些元素可以是整数、浮点数、布尔值或其他数据类型,它们在内存中连续存储,共同构成一个一维数组结构。向量处理器旨在高效处理大量数据的并行运算。
元素同质:向量中的所有元素具有相同的类型和大小。
一个双精度浮点数向量包含若干个连续存储的双精度浮点数。
连续存储:向量中的元素在内存中按顺序排列,相邻元素之间的地址差异固定(即元素间间隔等于元素大小)。这种布局有利于通过一次内存访问获取或写入多个连续数据,充分利用现代存储系统的带宽优势。
长度可变:虽然向量的长度通常在硬件设计时有一定限制(如VMIPS架构中默认为64个元素),但在软件层面,向量的长度可以根据实际应用需求动态变化。向量处理器通常支持处理不同长度的向量,通过向量长度寄存器来指定当前操作的有效元素数量。
并行处理:向量处理器设计的核心理念是同时对向量中的所有元素执行相同的运算。一条向量指令能够对整个向量的所有元素进行操作,如加法、乘法、比较、逻辑运算等。
向量化编程模型:向量体系结构支持向量化编程,即编写针对向量数据的操作代码。程序员可以通过高级语言的向量化库或特定的向量编程语言(如Fortran、OpenCL、CUDA等)来编写高效利用向量硬件的代码。编译器会负责将向量化代码转换为底层的向量指令序列。
所以向量我的理解可以看成C语言中的一个存放数的长度固定的数组。(比如泰勒展开式中的所有系数需要使用向量存储,也就是一个浮点数数组。)
向量体系结构是指指向向量并行运算的体系结构,具有一下的特点:
(1)大型顺序寄存器堆:向量处理器包含一组容量远大于传统CPU寄存器的大规模寄存器堆。这些寄存器可以同时存储一个数据向量的所有元素。这样设计使得处理器能够在单一指令周期内对整个向量的所有元素进行相同的操作。
(2)单条指令对向量操作:向量处理器支持向量化指令,即一条指令就能对寄存器堆中的所有数据元素执行相同的操作。对于一个包含64个元素的向量,只需一条指令就能完成64次“寄存器-寄存器”操作。这些操作可以包括算术运算(加、减、乘、除)、逻辑运算、比较等。
(3)隐藏存储器延迟:由于内存访问速度相对于处理器内部操作速度而言较慢,因此向量体系结构通过利用大型寄存器堆作为编译器管理的缓冲区来隐藏存储器访问延迟。当处理器需要访问内存中的数据时,它会以向量的形式批量加载多个连续数据元素到寄存器堆中。同样,处理完的结果也会以向量形式一次性写回内存。这种批量数据传输方式减少了与内存交互的次数,从而降低了总体的存储器访问延迟影响。
(4)流水线化向量载入和存储:向量处理器通常会对向量载入和存储操作进行流水线化处理。
尽管单次向量载入或存储可能需要较长的存储器延迟时间,但由于这些操作能够并行启动和独立执行,所以在等待某一批数据载入的同时,处理器可以继续处理已载入的数据或者启动下一批数据的载入。
(5)充分利用存储器带宽:由于向量处理器以批量方式访问内存,每次操作涉及大量数据元素,因此它能更好地利用现代存储系统的高带宽特性。相比传统的逐元素访问方式,向量访问模式能更充分地填满数据总线,实现更高的数据吞吐率,使存储器保持繁忙状态,进一步提升整体性能。
VMIPS架构
该架构融合了MIPS标量处理器和其逻辑向量扩展,形成一个混合型指令集体系结构。
1.向量寄存器:
(1)数量与容量:VMIPS包含8个向量寄存器,每个寄存器能存储64个元素,每个元素宽度为64位。这意味着每个向量寄存器可容纳总共64 × 64 = 4096位的数据,适用于存储大规模并行计算所需的大量数值数据。
(2)端口与重叠操作:为了支持高效的数据传输,向量寄存器堆提供了充足的端口,确保数据能被馈送到所有向量功能单元。
2.向量功能单元:
(1)数量与功能:VMIPS拥有5个向量功能单元,每个单元完全实现了流水线化设计,能在每个时钟周期开始一个新的操作。这些功能单元专用于执行向量数据的算术、逻辑、比较等操作。
(2)冒险检测:为了保证正确执行和避免潜在的错误,有一个控制单元负责检测两种类型的冒险:结构性冒险(如资源冲突)和数据冒险(如依赖于未完成计算结果的指令)。控制单元通过适当的调度和转发机制来解决这些问题,确保指令流水线的稳定运行。
3. 向量载入/存储单元:
(1)功能:此单元负责在向量寄存器与主存储器之间进行向量数据的载入和存储。它是完全流水线化的,意味着在初始延迟(如存储器访问延迟)之后,可以以每个时钟周期一个字(64位)的速率在两者之间传输数据。这种设计有助于减少存储器访问瓶颈,提高数据吞吐率。
(2)标量处理:除了处理向量数据,该单元还负责标量数据的载入和存储操作。此外,它还能计算向量载入/存储操作所需的内存地址,可能利用来自标量寄存器堆的信息。
4. 标量寄存器集合:
(1)量寄存器堆包含了MIPS架构的典型配置,即32个通用寄存器和32个浮点寄存器,用于存储和处理非向量(即标量)数据。
(2)标量寄存器不仅能为向量功能单元提供数据输入,参与向量运算,还用于计算向量载入/存储操作所需的内存地址。当向量功能单元从标量寄存器堆读取标量值时,会锁定这些值以确保数据一致性。
VMIPS架构的指令
在VMIPS架构中,向量运算指令的设计与标量MIPS指令紧密相关,但通过特定的后缀加以区分,以适应向量数据的处理需求。
向量指令命名
向量运算指令名称与对应的标量MIPS指令相同,但在末尾添加了字母“VV”,以表示这是一个针对向量数据的操作。
例如,标量MIPS指令中的“ADD.D”(双精度浮点数加法)在VMIPS中对应为“ADVV.D”,表示对两个双精度向量进行加法运算。
向量运算输入源:
向量运算的输入源可以是一对向量寄存器。
例如,“ADDVV.D”指令表示将两个双精度向量寄存器中的对应元素相加。
向量运算的输入源也可以是一个向量寄存器和一个标量寄存器,此时通过在指令名称后附加“VS”来标识。
例如,“ADDVS.D”指令表示将一个双精度向量寄存器中的每个元素分别加上一个标量寄存器中的相同值。这种情况下,向量功能单元在执行指令时会获取标量值的一个副本,并将其与向量寄存器中的每个元素进行相应操作。
向量运算结果
大多数向量运算会产生一个新的向量结果,该结果通常存储在一个向量目标寄存器中。
例如,上述的“ADDVV.D”和“ADDVS.D”指令都会将运算结果写回到指定的向量寄存器。
部分向量运算可能产生一个标量结果,而非向量。这类运算通常涉及到对向量数据的某种汇总或统计操作(如人口计数),其结果会被存储在标量寄存器中。
在VMIPS架构中,向量载入和存储操作分别由指令“LV”和“SV”表示,它们专门用于高效地从存储器中载入或向存储器中写入整个双精度数据向量。
LV(向量载入):LV指令有两个操作数。第一个操作数是要载入数据的目标向量寄存器,即将从存储器中读取的双精度数据向量存储到该向量寄存器中。第二个操作数是一个MIPS通用寄存器,它存放的是该向量在主存储器中的起始地址。这意味着,处理器将从指定地址开始,连续读取双精度数据,直到填满目标向量寄存器(默认情况下为64个元素)。
SV(向量存储):SV指令同样有两个操作数。第一个操作数是要写入存储器的源向量寄存器,即从该向量寄存器中取出双精度数据向量并写入存储器。第二个操作数也是一个MIPS通用寄存器,它存放的是存储器中目标区域的起始地址。处理器将从源向量寄存器中依次取出双精度数据,按照指定地址连续写入存储器,直至完成整个向量的存储。
VMIPS架构中还引入了两个额外的通用寄存器
(1)向量长度寄存器:当向量长度不等于默认的64个元素时,可以使用向量长度寄存器来指定实际的向量长度。在执行LV或SV指令时,处理器会根据该寄存器中的值来确定实际需要载入或存储的元素数量,而非默认的64个。这样,即使向量大小变化,也能确保正确且高效地处理数据。
(2)向量遮罩寄存器:在涉及循环中的条件分支(如IF语句)时,向量遮罩寄存器用于指示哪些向量元素应参与当前的运算或存储操作。遮罩寄存器中的每一位对应向量中的一个元素,若该位为1,则对应的元素参与操作;若为0,则元素被忽略。通过这种方式,程序员可以在循环中根据特定条件动态选择向量中的部分元素进行处理,无需中断向量流水线,从而保持高效的向量计算性能。