SIMD——MMX指令集介绍
MMX指令集共47个指令,分为以下几类:
• Data transfer
• Arithmetic
• Comparison
• Conversion
• Unpacking
• Logical
• Shift
• Empty MMX state instruction (EMMS)
1. Data Transfer(数据转移)
从内存到MMX寄存器/ 从MMX寄存器到内存/ 从通用寄存器到MMX寄存器/ 从MMX寄存器到通用寄存器
- MOVD 指令(32位)——4个
指令 | 函数 | 指令描述 |
---|---|---|
movd |
__m64 _mm_cvtsi32_si64(int a) __m64 _m_from_int(int a) |
变量a的32位拷贝到MMX寄存器的低32位,高32位置零 |
movd |
int _mm_cvtsi64_si32 (__m64 a) int _m_to_int(__m64 a) |
MMX变量的低32位拷贝到int类型中 |
根据 https://msdn.microsoft.com/zh-cn/8w48hs3e(v=vs.80) 所属 _mm_cvtsi32_si64 与 _m_from_int 应相同。(请指点)
+MOVQ指令(64位)——4个
指令 | 函数 | 指令描述 |
---|---|---|
movq |
__int64 _mm_cvtm64_si64(__m64 a) __int64 _m_to_int64(__m64 a) |
拷贝64位整型a到结果 |
movq |
__m64 _mm_cvtsi64_m64 (__int64 a) __m64 _m_from_int64(__int64 a) |
拷贝64位整型a到结果 |
2.Arithmetic(数值计算)
进行压缩整数的加减乘以及multiply/add计算。
加法(7个指令,14个函数):
指令 | 函数 | 指令描述 |
---|---|---|
paddw |
__m64 _mm_add_pi16(__m64 a, __m64 b) __m64 _m_paddw(__m64 a, __m64 b) |
Add packed word integers(16位) with wraparound 使用wraparound截断溢出方式进行压缩字整数的加运算 |
paddd |
__m64 _mm_add_pi32(__m64 a, __m64 b) __m64 _m_paddd (__m64a, __m64 b) |
Add packed doubleword integers(32位) with wraparound 使用wraparound截断溢出方式进行压缩双字整数的加运算 |
paddb |
__m64 _mm_add_pi8(__m64 a, __m64 b) __m64 _m_paddb (__m64a, __m64 b) |
Add packed byte integers(8位) with wraparound 使用wraparound截断溢出方式进行压缩字节整数的加运算 |
paddsw |
__m64 _mm_adds_pi16(__m64 a, __m64 b) __m64 _m_paddsw(__m64 a, __m64 b) |
Add packed word integers with signed saturation 压缩字整数的有符号饱和加运算 |
paddsb |
__m64 _mm_adds_pi8(__m64 a, __m64 b) __m64 _m_paddsb(__m64 a, __m64 b) |
Add packed byte integers with signed saturation 压缩字节整数的有符号饱和加运算 |
paddusw |
__m64 _mm_adds_pu16(__m64 a, __m64 b) __m64 _m_paddusw(__m64 a, __m64 b) |
Add packed word integers with unsigned saturation 压缩字整数的无符号饱和加运算 |
paddusb |
__m64 _mm_adds_pu8(__m64 a, __m64 b) __m64 _m_paddusb(__m64 a, __m64 b) |
Add packed byte integers with unsigned saturation 压缩字节整数的无符号饱和加运算 |
减法(7个指令,14个函数):
指令 | 函数 | 指令描述 |
---|---|---|
psubw |
__m64 _mm_sub_pi16(__m64 a, __m64 b) __m64 _m_psubw(__m64 a, __m64 b) |
sub packed word integers(16位) with wraparound 使用wraparound截断溢出方式进行压缩字整数的减运算 |
psubd |
__m64 _mm_sub_pi32(__m64 a, __m64 b) __m64 _m_psubd (__m64a, __m64 b) |
sub packed doubleword integers(32位) with wraparound 使用wraparound截断溢出方式进行压缩双字整数的减运算 |
psubb |
__m64 _mm_sub_pi8(__m64 a, __m64 b) __m64 _m_psubb (__m64a, __m64 b) |
sub packed byte integers(8位) with wraparound 使用wraparound截断溢出方式进行压缩字节整数的减运算 |
psubsw |
__m64 _mm_subs_pi16(__m64 a, __m64 b) __m64 _m_psubsw(__m64 a, __m64 b) |
sub packed word integers with signed saturation 压缩字整数的有符号饱和减运算 |
psubsb |
__m64 _mm_subs_pi8(__m64 a, __m64 b) __m64 _m_psubsb(__m64 a, __m64 b) |
sub packed byte integers with signed saturation 压缩字节整数的有符号饱和减运算 |
psubusw |
__m64 _mm_subs_pu16(__m64 a, __m64 b) __m64 _m_psubusw(__m64 a, __m64 b) |
sub packed word integers with unsigned saturation 压缩字整数的无符号饱和减运算 |
psubusb |
__m64 _mm_subs_pu8(__m64 a, __m64 b) __m64 _m_psubusb(__m64 a, __m64 b) |
sub packed byte integers with unsigned saturation 压缩字节整数的无符号饱和减运算 |
乘法(2个指令,4个函数)
指令 | 函数 | 指令描述 |
---|---|---|
pmulhw |
__m64 _mulhi_pi16(__m64 a, __m64 b) __m64 _m_pmulhw (__m64 a,__m64 b) |
压缩16位字整数a和b相乘会产生32位双字整数,将32位整数的高16位存储在结果中 |
pmullw |
__m64_mullo_pi16(__m64 a, __m64 b) __m64 _m_pmullw(__m64 a,__m64 b) |
压缩16位字整数a和b相乘会产生32位双字整数,将32位整数的低16位存储在结果中 |
具体的执行方式请参考下图,若使用pmulhw则乘法结果中的高16位存储在C中,若使用pmullw则乘法结果中的低16位存储在C中。
multiply/add(乘法加和,1个指令,2个函数)
指令 | 函数 | 指令描述 |
---|---|---|
pmaddwd |
__m64 _madd_pi16(__m64 a, __m64 b) __m64 _m_pmaddwd (__m64 a,__m64 b) |
压缩16位字整数a和b相乘会产生32位双字整数,a和b中后2个8位的相乘结果的和保存在结果的低32位,前2个16位相乘结果的和保存在结果的高32位中 |
具体的执行情况参考下图:
3. Comparision(比较操作)
指令 | 函数 | 指令描述 |
---|---|---|
pcmpeqb |
__m64 _mm_cmpeq_pi8 (__m64 a, __m64 b) __m64 _m_pcmpeqb (__m64 a, __m64 b) |
比较a和b里的8位字节整数值进行比较,判断它们是否相等,相等返回OxFFFF,否则返回0 |
pcmpeqw |
__m64 _mm_cmpeq_pi16 (__m64 a, __m64 b) __m64 _m_pcmpeqw (__m64 a, __m64 b) |
比较a和b里的16位字整数值进行比较,判断它们是否相等,相等返回OxFFFF,否则返回0 |
pcmpeqd |
__m64 _mm_cmpeq_pi32 (__m64 a, __m64 b) __m64 _m_pcmpeqd (__m64 a, __m64 b) |
比较a和b里的32位双字整数值进行比较,判断它们是否相等,相等返回OxFFFF,否则返回0 |
pcmpgtb |
__m64 _mm_cmpgt_pi8 (__m64 a, __m64 b) __m64 _m_pcmpgtb (__m64 a, __m64 b) |
比较a和b里的8位字节整数值,如果a中>b中,放回OxFFFF,否则返回0 |
pcmpgtw |
__m64 _mm_cmpgt_pi16 (__m64 a, __m64 b) __m64 _m_pcmpgtw (__m64 a, __m64 b) |
比较a和b里的16位字整数值,如果a中>b中,放回OxFFFF,否则返回0 |
pcmpgtd |
__m64 _mm_cmpgt_pi32 (__m64 a, __m64 b) __m64 _m_pcmpgtd (__m64 a, __m64 b) |
比较a和b里的32位双字整数值,如果a中>b中,放回OxFFFF,否则返回0 |
4. Conversion(打包指令)
指令 | 函数 | 指令描述 |
---|---|---|
packsswb |
__m64 _mm_packs_pi16 (__m64 a, __m64 b) __m64 _m_packsswb (__m64 a, __m64 b) |
将压缩16位字整数a和bpack成8位字节整数使用有符号饱和运算,保存到结果中 |
packssdw |
__m64 _mm_packs_pi32 (__m64 a, __m64 b) __m64 _m_packssdw (__m64 a, __m64 b) |
将压缩32位双字整数a和b pack成16位字整数使用有符号饱和运算,保存到结果中 |
packuswb |
__m64 _mm_packs_pu16 (__m64 a, __m64 b) __m64 _m_packuswb (__m64 a, __m64 b) |
将压缩16位字整数a和b pack成8位字节整数使用无符号饱和运算,保存到结果中 |
packsswb:
dst[7:0] := Saturate_Int16_To_Int8 (a[15:0])
dst[15:8] := Saturate_Int16_To_Int8 (a[31:16])
dst[23:16] := Saturate_Int16_To_Int8 (a[47:32])
dst[31:24] := Saturate_Int16_To_Int8 (a[63:48])
dst[39:32] := Saturate_Int16_To_Int8 (b[15:0])
dst[47:40] := Saturate_Int16_To_Int8 (b[31:16])
dst[55:48] := Saturate_Int16_To_Int8 (b[47:32])
dst[63:56] := Saturate_Int16_To_Int8 (b[63:48])
packssdw:
dst[15:0] := Saturate_Int32_To_Int16 (a[31:0])
dst[31:16] := Saturate_Int32_To_Int16 (a[63:32])
dst[47:32] := Saturate_Int32_To_Int16 (b[31:0])
dst[63:48] := Saturate_Int32_To_Int16 (b[63:32])
packuswb:
dst[7:0] := Saturate_Int16_To_UnsignedInt8 (a[15:0])
dst[15:8] := Saturate_Int16_To_UnsignedInt8 (a[31:16])
dst[23:16] := Saturate_Int16_To_UnsignedInt8 (a[47:32])
dst[31:24] := Saturate_Int16_To_UnsignedInt8 (a[63:48])
dst[39:32] := Saturate_Int16_To_UnsignedInt8 (b[15:0])
dst[47:40] := Saturate_Int16_To_UnsignedInt8 (b[31:16])
dst[55:48] := Saturate_Int16_To_UnsignedInt8 (b[47:32])
dst[63:56] := Saturate_Int16_To_UnsignedInt8 (b[63:48])
5.Unpack(解包指令)
指令 | 函数 | 指令描述 |
---|---|---|
punpckhbw |
__m64 _m_punpckhbw (__m64 a, __m64 b) __m64 _mm_unpackhi_pi8 (__m64 a, __m64 b) |
64位a和b数据的高一半位数数据(32位)保存到结果中,具体保存方式参考如下描述 |
punpckhwd | ||
punpckhdq | ||
punpcklbw | ||
punpcklwd | ||
punpckldq |
packsswb:
INTERLEAVE_HIGH_BYTES(src1[63:0], src2[63:0]){dst[7:0] := src1[39:32]dst[15:8] := src2[39:32] dst[23:16] := src1[47:40]dst[31:24] := src2[47:40]dst[39:32] := src1[55:48]dst[47:40] := src2[55:48]dst[55:48] := src1[63:56]dst[63:56] := src2[63:56]RETURN dst[63:0]
} dst[63:0] := INTERLEAVE_HIGH_BYTES(a[63:0], b[63:0])
6. Logical(逻辑运算)
指令 | 函数 | 指令描述 |
---|---|---|
pand | ||
pandn | ||
por | ||
pxor |
7. Shift(移位)
指令 | 函数 | 指令描述 |
---|---|---|
psllw | ||
pslld | ||
psllq | ||
psrlw | ||
psrld | ||
psrlq | ||
psraw | ||
psrad |
8. EMMS
指令 | 函数 | 指令描述 |
---|---|---|
emms | void _m_empty (void)void _mm_empty (void) | 使用 EMMS 命令与空容器以容纳新目录 |
EMMS使用方法:
1. 如果下一条命令是浮点命令,请在MMX指令后使用_mm_empty(例如在进行float,double和long double 类型的计算前)
2. 当寄存器中不存在MMX寄存时,不要使用EMMS指令。如果下一个命令使用MMX寄存器,使用EMMS没有好处(不会进行优化)
3.
SIMD——MMX指令集介绍相关推荐
- SIMD补充 指令集架构类型 指令集介绍
文章目录 SIMD 指令集架构类型 CISC的产生.发展和现状 RISC的产生.发展和现状 IA-64(EPIC)产生.发展和现状 RISC与 IA-64(EPIC)相比 指令集介绍 一.X86 二. ...
- Intel 64/x86_64/IA-32/x86处理器 - SIMD指令集 - SSE扩展(9) - 64位整型指令(MMX指令集扩展)
SSE 64-Bit SIMD Integer Instructions SSE扩展增加了几条64位组合的整型指令,这些指令操作MMX寄存器和64位的存储器操作数,这些指令可以看作是对MMX指令集的扩 ...
- 深入探讨用位掩码代替分支(7):MMX指令集速度测试
前面我们测试了高级语言做饱和处理的性能.其实,对于这样的大批量数据处理,使用SIMD(Single Instruction Multiple Data,单指令多数据流)技术能极大的提高性能.MMX指令 ...
- MMX的数据结构 MMX指令集
源地址:http://dev.gameres.com/Program/Other/MMXData.htm http://www.360doc.com/content/12/1129/18 ...
- C/C++指令集介绍以及优化(主要针对SSE优化)
前言:最近在做一些OpenCV的优化相关的东西,发现OpenCV现在的执行效率很高的原因一部分是来自于底层的优化,比如指令集优化,但是一直没找到比较系统性的关于CPU指令集优化的文章或者是书籍,于是自 ...
- 【笔记】COA课内实验-MMX指令集
前言 参考资料 关于BMP文件格式的详解 SetDIBitsToDevice函数 SetDIBitsToDevice function | Microsoft docs BITMAPINFO stru ...
- luaJIT指令集介绍
luaJIT指令集介绍 ----------------目录--------------- (a)相关ByteCode定义介绍 (b)lj_bc.h和lj_bc.c (1)字节码format简介 (2 ...
- 深入iOS系统底层之指令集介绍
程序员大咖点击右侧关注,免费进阶高级! 作者:欧阳大哥2013 链接:https://www.jianshu.com/p/54884ce976ca 任何形式的转载都请联系作者获得授权并注明出处. 说到 ...
- 论ARMv7 Thumb-2指令集的性能(含Thumb指令集介绍)【转载】
[摘要] 主要是介绍ARM CPU中的THUMB-2功能,相对于THUMB的比较THUMB-2指令集的扩展,THUMB-2的新指令带来的好处,新指令对性能和代码密度的改进. 如今的嵌入式系统开发 ...
最新文章
- Linux内核网络栈1.2.13-route.c概述
- [React] Web应用:Hello World
- XenServer中Fast Copy与Full Copy的区别
- pixhawk软件架构
- Ubuntu14.04无法在var/www内新建文档
- 洛谷3672:小清新签到题——题解
- IPv6报文格式讲解及其科学性探究
- Python3对IP进行查询
- 中科大和东北大学计算机考研,我国39所985高校,一共被分为五个档次,复旦大学处于第二档...
- linux 配置 NTP 服务器
- FPGA | Vivado 查看最大工作频率(Fmax)
- sysprep无法验证你的windows安装_Sysprep无法验证你的windows 安装。
- 23MySQL 是怎么保证数据不丢的
- 论文笔记--Exploring Translation Similarities for Building a Better Sentence Aligner
- 解决IOS微信浏览器底部会出现向前向后返回按钮问题
- 凌恩生物文献分享|转录组高级分析--植物抗性基因分析
- 均匀分布的均值及方差
- vue的form表单在提交成功后置空
- laravel表单提交419解决办法
- C++ QT QNetworkAccessManager 基操
热门文章
- cgns matlab,MATLABSimulink系统建模与仿真实验报告(详细解析)(word文档良心出品).docx...
- Python基础之算数运算符
- python爬虫实例网易云-爬虫实战(二) 用Python爬取网易云歌单
- 计算化学领域的黑科技
- node.js v14.9.0以及v12.18.3两版本 百度网盘下载链接
- 小米4可以刷入linux,小米4刷入SailfishOS系统图文教程(附工具)
- 【一行代码系列】Python 的多线程
- 圆周角、圆心角、弦、弦心距、弧长、扇形面积
- 【Android 10 源码】healthd 模块 HAL 2.0 分析
- Scrapy 爬取百度贴吧指定帖子的发帖人和回帖人