文章目录
SVE 使用介绍
前面文章:【ARMv8/ARMv9 硬件加速系列 1 -- SVE | NEON | SIMD | VFP | MVE | MPE 基础介绍】 已经对 SVE
做了个大概得介绍,接下来我们就会逐渐深入研究SVE
的使用。这里我们再回顾下 ARM 的 SVE :
ARMv9架构中的SVE(Scalable Vector Extension)和SVE2(Scalable Vector Extension 2)是为了增强处理器在处理高性能计算、机器学习、人工智能等领域的性能而设计的关键技术。它们提供了一种可伸缩的向量处理能力,允许更高效地对大量数据进行并行处理。
SVE 特点
SVE是在ARMv8-A架构中首次引入的一种向量扩展,旨在提供一种比传统SIMD(如ARM自己的NEON技术)更灵活的方式来处理向量计算。SVE的关键特性包括:
- 可伸缩的向量长度 :SVE支持从128 位到2048位的可伸缩向量长度,向量长度可以根据目标处理器的具体实现而变化。这种可伸缩性允许SVE代码在不同的ARM处理器上运行,而不需要为每个处理器重写代码。
- 谓词执行:通过谓词寄存器,SVE支持掩码执行,允许对向量中的每个元素独立地进行条件执行。这提高了代码的灵活性和效率。
- 向量化循环:SVE专门优化了向量化循环的执行,使得循环能够更高效地利用向量化指令。
SVE2 特点
SVE2是SVE的扩展,随ARMv8.2-A及后续版本提供,进一步增强了SVE的能力,特别是针对复杂的数据处理模式。SVE2的新增特性包括:
- 增强的整数和浮点运算:SVE2引入了更多的整数和浮点向量指令,支持更广泛的数据处理需求。
- 复杂的数据重排操作:SVE2提供了丰富的数据重排(permutation)和交错(interleaving)操作,这对于实现复杂的算法(如加密算法)非常有用。
- 增强的字符和字符串处理:为了支持更高效的文本和数据处理,SVE2加入了针对字符和字符串操作的指令。
- 兼容性:SVE2设计为与SVE向后兼容,意味着能够执行SVE指令的处理器同样能够执行SVE2指令。
在高性能计算和人工智能领域,可以利用SVE和SVE2的强大能力来加速计算密集型任务。例如,使用SVE/SVE2进行矩阵乘法运算可以大幅提升深度学习模型训练和推理的速度。通过利用可伸缩的向量长度和谓词执行,开发者可以编写出既高效又灵活的代码,适配不同的硬件实现,以最大化性能和资源利用率。
总之,SVE和SVE2通过提供可伸缩的向量长度和一系列高级向量处理指令,大大增强了ARM架构在高性能计算、机器学习和人工智能应用中的竞争力。
SVE 寄存器
SVE寄存器有4种:
- 32个可扩展的向量寄存器,
Z0-Z31
; - 16个可扩展的谓词寄存器,
P0-P15
; - 一个First Fault 谓词寄存器(
FFR
); - 可扩展的向量系统控制寄存器
ZCR_Elx
。
扩展的向量寄存器
SVE共有32 个可变长矢量寄存器Z0-Z31
(128 位的整数倍, 最高可达2048 位) ,其中Z0-Z31
的低128
位[127:0]
,与AArch64 SIMD
&FP
寄存器V0-V31
共享硬件资源。假设SVE
的矢量长度为256
,其矢量寄存器 视图如下:
-
可以支持64bits,32bits,16bits 和 8 bits 的元素;
-
支持整型以及双精度,单精度和半精度浮点元素;
-
可配置每个异常级别 (EL) 的向量长度。
-
.d
后缀 :表示操作的数据类型为双字(64位)。当你使用.d
后缀(如p0.d
)时,这表示谓词寄存器中的每一位控制向量寄存器中对应的64位数据元素。通常用于精细控制对64位数据元素的操作。 -
.b
后缀 :表示操作的数据类型为字节(8位)。使用.b
后缀(如p0.b
)时,每一位控制向量寄存器中对应的8位数据元素。这允许对向量寄存器中的单个字节进行更细粒度的控制。
可扩展的谓词寄存器
SVE 谓词寄存器 用于控制每通道操作,有16
个可变长预测寄存器P0-P15
,向量寄存器用于存储实际的数据,而谓词寄存器用于控制向量指令的条件执行。假设SVE
的矢量长度为256
,谓词寄存器在管理32
位和64
位操作时,其视图如下:
谓词寄存器通常被用作对数据操作的 bit mask:
- 每个谓词寄存器是
Zx
(可扩展向量寄存器)的1 / 8
P0-P7
是控制加载、存储和算术的谓词。P8-P15
是用于循环管理的额外的谓词。
SVE引入了谓词寄存器(如p0
到p15
),这些寄存器用于控制向量操作的执行。谓词寄存器中的每一位对应向量寄存器中的一个元素,指示该元素是否应该参与到特定的向量操作中。
- 当谓词寄存器位为
1
时,相应的向量操作会在对应的元素上执行; - 当谓词寄存器位为
0
时,相应的元素不会被操作。
接下来将介绍 .d
与.b
后缀在谓词寄存器使用中的区别,并通过例子进行说明。
.d 与 .b 后缀的区别
.d
后缀 :表示操作的数据类型为双字(64位)。当你使用.d
后缀(如p0.d
)时,这表示谓词寄存器中的每一位控制向量寄存器中对应的64位数据元素。通常用于精细控制对64位数据元素的操作。.b
后缀 :表示操作的数据类型为字节(8位)。使用.b
后缀(如p0.b
)时,每一位控制向量寄存器中对应的8位数据元素。这允许对向量寄存器中的单个字节进行更细粒度的控制。
举例介绍
假设我们现在有一个需求,对两个向量z0
和z1
中的数据进行条件性处理,分别涉及对64位(双字)和8位(字节)元素的操作。
使用 .d 后缀进行64位元素操作
assembly
// 设置p0,使其对64位元素全开
ptrue p0.d
// 假设z0和z1是两个64位元素的向量
// 使用p0控制的条件加法,只有在p0对应位为真时,z0和z1中对应的64位元素才会相加
add z2.d, p0/m, z0.d, z1.d
在这个例子中,ptrue p0.d
指令设置p0
中的每一位都为真,表示每一个64位的元素都应该参与下一条add
指令的执行。这样,z0
和z1
中的对应64位元素被相加,结果存储在z2
中。
使用 .b 后缀进行8位元素操作
assembly
// 设置p1,使其对8位元素全开
ptrue p1.b
// 假定z3和z4是包含8位元素的向量
// 使用p1控制的条件加法,只有在p1对应位为真时,z3和z4中对应的8位元素才会相加
add z5.b, p1/m, z3.b, z4.b
在这个例子中,ptrue p1.b
指令设置p1
中的每一位都为真,意味着每个8位的元素都参与下一条add
指令的执行。这样,z3
和z4
中的对应8位元素被相加,结果存储在z5
中。
ptrue 指令
ptrue
指令用于将谓词寄存器中的元素设置为真(TRUE),指示后续的向量操作应该在所有元素上执行。- 例如,
ptrue p0.b
将p0
寄存器中所有的位设置为真,.b
表示操作的最小数据单元是 byte。
小结
.d
和.b
后缀在谓词寄存器使用中代表了操作的数据类型(分别是64位和8位),这允许开发者根据需要对向量寄存器中的数据进行精细的控制。通过使用不同的后缀,可以实现对不同数据大小元素的条件处理,使SVE在处理向量数据时更加灵活和强大。
FFR 寄存器
First Fault Register (FFR) 是一个特殊的谓词寄存器,由 first-fault 加载和存储指令设置,用于指示每个元素的加载和存储操作的成功程度。 FFR 旨在支持推测性内存访问,这使得向量化在许多情况下更容易和更安全。
推荐阅读 :
https://blog.csdn.net/AngelLover2017/article/details/124808387