LoongArch64 主观亮点
引言
最近我重新开始研究 simdutf,发现这个库已经支持了 LoongArch64。这是中国龙芯公司设计的自定义架构和自定义指令集架构(ISA)。他们提供了标量指令集的文档,但没有提供向量扩展的文档。尽管如此,GCC、binutils、QEMU 和其他工具已经支持这个指令集。幸运的是,陈嘉杰(Jiajie Chen)对向量扩展进行了逆向工程,并将结果发布在网上,名为 非官方 LoongArch 内联函数指南。
LoongArch 提供了两种向量扩展:
- LSX,拥有 128 位的向量寄存器,
- LSAX,拥有 256 位的向量寄存器。
这些扩展非常相似,尤其是 LSX 中的大多数指令在 LSAX 中也存在。根据维基百科的条目,这个指令集是 RISC-V 和 MIPS 的混合体。
指令集支持整数和浮点指令。支持 8 位、16 位、32 位、64 位以及 128 位的整数。浮点指令涵盖单精度、双精度和半精度数。
比较操作会生成字节掩码,类似于 SSE。
整数指令为大多数整数类型定义,这使得指令集非常规整。
我的印象是这个指令集设计得很好,但我还没有为该架构向量化任何代码。以下是我在浏览内联函数指南时发现的一些有趣的功能。
个人亮点
条件分支
可以根据两个谓词控制程序流程:
- 如果向量中的任何元素为零,
- 如果向量中的所有元素都非零。
类似的解决方案存在于 SSE 中(PTEST),但它作用于整个向量,而不是向量元素。
位操作
有一些向量指令可以修改字中的单个位:
- 设置一个位,
- 重置一个位,
- 切换一个位。
这真的很酷(在具有可变移位的 SIMD 指令集中很容易实现)。
位计数
定义了以下计数操作:
- 计算前导零,
- 计算前导一,
- 计算人口数(计算一的个数)。
计算前导零和人口数仅在 AVX-512 中存在。
128 位算术
- 有 128 位数的加法和减法。非常棒!
- 可以从 128 位字中选择任何 64 位子字。
整数绝对值
有两个与绝对值相关的指令。
- 计算差值的绝对值:
dst[i]=a[i]>b[i]?a[i]-b[i]:b[i]-a[i];
- 绝对值的和:
dst[i]=abs(a[i])+abs(b[i]);