【转载】:SIMD(MMX/SSE/AVX)变量命名规范心得
当使用
Intrinsics
函数来操作
SIMD
指令集(
MMX/SSE/AVX
等)时,会面对不同长度的
SIMD
数据类型,其中又分为多种紧缩格式。为此,我设计了一套
SIMD
变量命名规范,可以有效的提高代码的可读性。
1、SIMD数据类型简介
SIMD数据类型有:
__m64 :64位紧缩整数(MMX)。
__m128 :128位紧缩单精度(SSE)。
__m128d :128位紧缩双精度(SSE2)。
__m128i :128位紧缩整数(SSE2)。
__m256 :256位紧缩单精度(AVX)。
__m256d :256位紧缩双精度(AVX)。
__m256i :256位紧缩整数(AVX)。
注:紧缩整数包括了8位、16位、32位、64位的带符号和无符号整数。
这些数据类型与寄存器的对应关系为:
64 位MM寄存器 (MM0~MM7) : __m64。
128位SSE寄存器(XMM0~XMM15):__m128、__m128d、__m128i。
256位AVX寄存器(YMM0~YMM15):__m256、__m256d、__m256i。
SIMD 数据类型关键字:
p : 紧密,指令对寄存器中的每个元素进行运算
ep : 扩充紧密
s :标量,只将寄存器中的第一个元素参与运算
2、SIMD变量命名规范
参考匈牙利命名法(Hungarian notation),在变量名前面增加类型前缀。
类型前缀为3个小写字母,首字母代表寄存器宽度,最后两个字母代表紧缩数据类型。
寄存器宽度(首字母)——
m: 64位MM寄存器。 对应 __m64
x:128位SSE寄存器。对应 __m128、__m128d、__m128i。
y:256位AVX寄存器。对应 __m256、__m256d、__m256i。
紧缩数据类型(两个字母)——
mb:8位数据。用于只知道长度、不知道具体紧缩格式时。(b:Byte)
mw:16位数据。(w:Word)
md:32位数据。(d:DoubleWord)
mq:64位数据。(q:QuadWord)
mo:128位数据。(o:OctaWord)
mh:256位数据。(h:HexWord)
ub / uw / ud / uq:8位 / 16位 / 32位 / 64位 无符号整数。
ib / iw / id / iq :8位 / 16位 / 32位 / 64位 带符号整数。
fh:16位浮点数,即半精度浮点数。(h:Half)
fs:32位浮点数,即单精度浮点数。(s:Single)
fd:64位浮点数,即双精度浮点数。(d:double)
例如 ——
mub:64位紧缩字节(64位MMX寄存器,其中存放了8个8位无符号整数)。
xfs:128位紧缩单精度(128位SSE寄存器,其中存放了4个单精度浮点数)。
xid:128位紧缩带符号字(128位SSE寄存器,其中存放了4个32位带符号整数)。
yfd:256位紧缩双精度(256位AVX寄存器,其中存放了4个双精度浮点数)。
yfh:256位紧缩半精度(256位AVX寄存器,其中存放了16个半精度浮点数)。
3、示例代码
SSE累加求和程序 :
此处再给出了第二种写法:
测试上面的函数:
上述测试代码中的 __declspec(align(16)) 主要是为了让数据 a 的地址是16字节对齐。否则的话 _mm_load_si128 会报错。也可以将函数_mm_load_si128 改为 _mm_loadu_si128,这样就不需要将数组进行16字节对齐,也可以获得正确结果,但是效率可能会低一些。
1、SIMD数据类型简介
SIMD数据类型有:
__m64 :64位紧缩整数(MMX)。
__m128 :128位紧缩单精度(SSE)。
__m128d :128位紧缩双精度(SSE2)。
__m128i :128位紧缩整数(SSE2)。
__m256 :256位紧缩单精度(AVX)。
__m256d :256位紧缩双精度(AVX)。
__m256i :256位紧缩整数(AVX)。
注:紧缩整数包括了8位、16位、32位、64位的带符号和无符号整数。
这些数据类型与寄存器的对应关系为:
64 位MM寄存器 (MM0~MM7) : __m64。
128位SSE寄存器(XMM0~XMM15):__m128、__m128d、__m128i。
256位AVX寄存器(YMM0~YMM15):__m256、__m256d、__m256i。
SIMD 数据类型关键字:
p : 紧密,指令对寄存器中的每个元素进行运算
ep : 扩充紧密
s :标量,只将寄存器中的第一个元素参与运算
2、SIMD变量命名规范
参考匈牙利命名法(Hungarian notation),在变量名前面增加类型前缀。
类型前缀为3个小写字母,首字母代表寄存器宽度,最后两个字母代表紧缩数据类型。
寄存器宽度(首字母)——
m: 64位MM寄存器。 对应 __m64
x:128位SSE寄存器。对应 __m128、__m128d、__m128i。
y:256位AVX寄存器。对应 __m256、__m256d、__m256i。
紧缩数据类型(两个字母)——
mb:8位数据。用于只知道长度、不知道具体紧缩格式时。(b:Byte)
mw:16位数据。(w:Word)
md:32位数据。(d:DoubleWord)
mq:64位数据。(q:QuadWord)
mo:128位数据。(o:OctaWord)
mh:256位数据。(h:HexWord)
ub / uw / ud / uq:8位 / 16位 / 32位 / 64位 无符号整数。
ib / iw / id / iq :8位 / 16位 / 32位 / 64位 带符号整数。
fh:16位浮点数,即半精度浮点数。(h:Half)
fs:32位浮点数,即单精度浮点数。(s:Single)
fd:64位浮点数,即双精度浮点数。(d:double)
例如 ——
mub:64位紧缩字节(64位MMX寄存器,其中存放了8个8位无符号整数)。
xfs:128位紧缩单精度(128位SSE寄存器,其中存放了4个单精度浮点数)。
xid:128位紧缩带符号字(128位SSE寄存器,其中存放了4个32位带符号整数)。
yfd:256位紧缩双精度(256位AVX寄存器,其中存放了4个双精度浮点数)。
yfh:256位紧缩半精度(256位AVX寄存器,其中存放了16个半精度浮点数)。
3、示例代码
SSE累加求和程序 :
测试上面的函数:
上述测试代码中的 __declspec(align(16)) 主要是为了让数据 a 的地址是16字节对齐。否则的话 _mm_load_si128 会报错。也可以将函数_mm_load_si128 改为 _mm_loadu_si128,这样就不需要将数组进行16字节对齐,也可以获得正确结果,但是效率可能会低一些。