SSE/AVX

时至今日,SSE 已经成为 x86 系统中默认开启的功能。SSE4 中,定义了 128 位寄存器及对应的 SIMD 指令,这成为了后续 AVX 继续设计的基础。 AVX2 比 SSE 略新,一般需要指定架构才编译,不过实际上在大部分的 x86 CPU 中都启用。AVX 中定义了 256 位的寄存器,但是这些寄存器通常是作为两个同样的 128 位寄存器(lane)使用,必须使用vperm或是vpack等少数指令才能跨越 128 位边界。 而 AVX512 是一组特性的集合,包括多个小的扩展,比如最基本的 AVX512F(Foundation)拓展了 512 位的寄存器,但使用上和上述的 256 位寄存器类似。更加重要的是,AVX2 指令集的空隙较多,如只定义了按偏移量读取数组的vgather系列指令,但没有定义对应的写入指令,这由 AVX512F 中的vpscatter系列指令补全。虽然 AVX512 的 512 位寄存器推出很早,但是由于 AVX512 指令能耗过高,对应指令很长一段时间内都需要由 CPU 降频运行,速度很可能不如 AVX2。直到最近的 Zen4、Zen5 才改变了现状,见:Zen4’s AVX512 Teardown Zen5’s AVX512 Teardown + More…

指令相关的资料,包括所用的头文件和 C 函数名,可以在 Intel® Intrinsics Guide 查看。

NEON

ARM 在 SIMD 方面则统一很多,只有一个 NEON 扩展,提供 128 位向量及浮点运算。NEON 的指令数量虽然不多,但设计相比 SSE/AVX 要整齐不少,比如在 swizzle 方面有包括vldN/vstN/vrev/vext/vtrn/vzip/vuzip/vtbl/vtbx等多个指令,参考:Permutation - Neon instructions

NEON 指令相关信息可以在 Intrinsics - Arm Developer 查看,注意里面的 Helium 是针对 M 系列 CPU 提出的 SIMD,又叫 MVE,而 SVE 目前在消费级产品上没有应用。NEON 所有的指令都位于#include <arm_neon.h>中。

宏定义

对于 GCC,使用下列命令获取架构相关的宏定义。

gcc -march=native -dM -E - < /dev/null | egrep "SSE|AVX|ARM" | sort

MSVC 的宏定义则直接在官网查看:Microsoft-specific predefined macros