SSE Instructions
SSE Instructions
记录一些 SSE 指令集最基础的东西,经常容易忘。
一些比较混的概念 SSE、MMX、XMM、SIMD
SIMD: Single instruction, multiple data 就是一条指令处理一组数据,描述指令集性质的一个缩写。
SSE 是 SIMD 指令集,支持同时处理多组数据(整数/浮点),属于 SIMD 指令集。 SSE 进一步升级还有SSE2,SSE3……
MMX 也是 SIMD 指令集,只不过是以前 IA32 的 SIMD 解决方案,缺点是占用 FPU 寄存器,浮点和 SIMD 不能同时处理,SSE 引入了 XMM 寄存器解决了这个问题。
SIMD 指令集主要用于多媒体操作吧,比如信号/图像处理,这些处理涉及到大量的矩阵运算。简单说,矩阵基本运算用 for 循环实现真的太拉垮。一般线性代数库就会用平台 SIMD 指令集优化计算算法,这也是为什么 ml 里面的各种公式最好要向量化实现。
寄存器
SSE 最基本的寄存器: XMM0 - XMM7: 128 bit registers
AMD64 (x86-64) / IA64: XMM8 - XMM15
SSE 指令
指令速查网站:https://software.intel.com/sites/landingpage/IntrinsicsGuide/
本文记录的指令有SSE,SSE2,SSE3
SSE 指令运算有两种类型 packed
和scalar
packed 多组数据一起运算
scalar 只有一组数据运算(标量运算)(低64/32位)
Floating-point instructions
内存 Load / Store
- Scalar –
MOVSS
- Packed –
MOVAPS, MOVUPS, MOVLPS, MOVHPS, MOVLHPS, MOVHLPS, MOVMSKPS
- MOVAPS,MOVUPS
- 区别:前者要求内存地址 16 字节对齐,后者不需要对齐。
- 共同:Load 完整 128 bit
movhps
- to/from the higher part ofxmm
register.movlps
- to/from the lower part ofxmm
.movhlps
- from higher part of source register to lower part of destination register.movlhps
- from lower part of source register to higher part of destination register.
运算
- Scalar –
ADDSS, SUBSS, MULSS, DIVSS, RCPSS, SQRTSS, MAXSS, MINSS, RSQRTSS
- Packed –
ADDPS, SUBPS, MULPS, DIVPS, RCPPS, SQRTPS, MAXPS, MINPS, RSQRTPS
比较
- Scalar –
CMPSS, COMISS, UCOMISS
- Packed –
CMPPS
数据改组(shuffle/unpacking)
- Packed –
SHUFPS, UNPCKHPS, UNPCKLPS
shuffle 机翻译出来就是改组,我也不知道翻译对不对。shuffle 将 XMM 寄存器中元素的顺序改变或者混和两个寄存器的值。
shufps 指令有 3 个操作数(2个XMM寄存器,8bit的掩码)
1 |
|
目的寄存器的前两个元素(低64bit)可以被覆盖成目的寄存器的任意两个元素。
目的寄存器的第三四元素(高32bit)可以被源寄存器任意两个元素。
imm8 掩码作用是控制元素的选择,掩码分成 4 组长度为2bit的数据 00 | 00 | 00 | 00,分别控制元素来源的选择。
00 - src[31:0]
01 - src[63:32]
10 - src[95:64]
11 - src[127:96]
src 可以是目的寄存器和源寄存器, 取决于目的寄存器中重组的位置。
intel 给的伪代码很清晰
1 |
|
数据类型转换
整数转浮点,浮点转整数
- Scalar –
CVTSI2SS, CVTSS2SI, CVTTSS2SI
,cvtsi2sd
,cvtsd2si
,cvttsd2si
- Packed –
CVTPI2PS, CVTPS2PI, CVTTPS2PI
- Integer to float/doubles
- cvtsi2ss, cvtsi2sd
- floats/doubles to integers
cvtss2si
convert 32-bit float to integer, round up/downcvttss2si
convert 32-bit float to integer, truncate resultcvtsd2si
convert 64-bit double to integer, roundcvttsd2si
convert 64-bit double to integer, truncate
Convert between floats and doubles
cvtss2sd
convert 32-bit float to 64-bit doublecvtsd2ss
convert 64-bit float to 32-bit float
先说一下命名,例如 CVTSI2SS
CVT + SI + 2 + SS:
- SI: Scalar Integer
- SS: Scalar Single Folat point
- 整数转单精度浮点
CVTSS2SI
CVT + SS + 2 + SI 即单精度浮点转整数
CVTTSS2SI
CVTT + SS + 2 + SI 也是单精度浮点转整数 (Truncation)
总结一下:
- SS: 标量,单精度浮点
- SI: 标量,整数
- SD: 标量,双精度浮点
- PS: 向量,单精度浮点
- PI:向量,整数
- PD: 向量,双精度
- US: unisgned 无符号
cvt
与 cvtt
有什么区别呢?
cvt
转换浮点时就近舍去浮点(四舍五入),cvtt
直接舍掉小数点后的数字保留整数部分(c/c++ 默认)
CVTPI2PS
CVT + PI + 2 + PS:
- PI: Packed Integer
- PS: packed Single Float
逻辑运算
- Packed –
ANDPS, ORPS, XORPS, ANDNPS
ANDPS
: AND + Packed + Single
Integer instructions
Arithmetic
PADDB
,PADDW
,PADDD
,PADDQ
,PADDSB
,PADDSB
PMULHUW, PSADBW, PAVGB, PAVGW, PMAXUB, PMINUB, PMAXSW, PMINSW
PADDSB
:Add packed signed byte integers with saturation
saturation 是运算比较特殊运行,可以运算将结果限制在某个区间内。
Data movement
PEXTRW, PINSRW
Other
PMOVMSKB, PSHUFW
参考
[1] https://en.wikipedia.org/wiki/Streaming_SIMD_Extensions “Streaming SIMD Extensions”
[2] https://blog.csdn.net/arau_sh/article/details/6161871 “MMX 和SSE指令集的区别是什么”
[3] https://stackoverflow.com/questions/16218665/simd-and-difference-between-packed-and-scalar-double-precision “SIMD and difference between packed and scalar double precision”
[4] https://students.mimuw.edu.pl/~zbyszek/asm/en/instrukcje-sse.html “SSE Instructions (Streaming SIMD Extensions)”
[5] https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_shuffle_ps&expand=5197 “Intrinsics Guide”
[6] https://blog.csdn.net/zp288105109a/article/details/100008264 “[汇编]汇编学习笔记(4):SHUFPS(洗牌)指令”
[6] https://www.cs.uaf.edu/2012/fall/cs301/lecture/10_26_asm_float.html “CS301: Floating Point in x86 Assembly”
[7] https://montcs.bloomu.edu/Presentations/Old/240/16.floating-point-SSE.pdf “Introduction to Scalar FloatingPoint Operations via SSE”
[8] https://en.wikipedia.org/wiki/X86_instruction_listings#SSE2_instructions “x86 instruction listings”
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!