SIMD指令集

**

概述

**
SIMD,即Single Instruction, Multiple Data,一条指令操作多个数据.是CPU基本指令集的扩展.主要用于提供fine grain parallelism,即小碎数据的并行操作.比如说图像处理,图像的数据常用的数据类型是RGB565, RGBA8888, YUV422等格式,这些格式的数据特点是一个像素点的一个分量总是用小于等于8bit的数据表示的.如果使用传统的处理器做计算,虽然处理器的寄存器是32位或是64位的,处理这些数据确只能用于他们的低8位,似乎有点浪费.如果把64位寄存器拆成8个8位寄存器就能同时完成8个操作,计算效率提升了8倍.SIMD指令的初衷就是这样的,只不过后来慢慢cover的功能越来越多.

好多处理器都有SIMD指令,我们先仅关注Intel的SIMD.

Intel的初代SIMD指令集是MMX,Multi-Media Extension, 即多媒体扩展,因为它的首要目标是为了支持MPEG视频解码.MMX将64位寄存当作2X32或8X8来用,只能处理整形计算.这样的64位寄存器有8组,分别命名为MM0~MM7.这些寄存器不是为MMX单独设置的,而是借用的FPU的寄存器,也就是说MMX指令执行的时候,FPU就没有办法工作.
在这里插入图片描述

后来Intel进一步实现了SSE, SSE2~SSE4指令集,给了他们单独的寄存器,之后MMX就被停掉了.

发展历史

SSE, SSE2一直到SSE4,AVX都是一代一代发展过来的,基本上是在原来的基础上增加一些功能,这个增加的过程在网上找到了一张图可以很好的解释.
在这里插入图片描述

图中可以看出,SSE首先就是有了属于自己的8个128位长的寄存器,即32x4,可以支持4个单精度浮点数同时计算,这8个寄存器称为XMM0~XMM7, SSE指令要求数据是16byte对齐的.SSE2则进一步支持双精度浮点数,由于寄存器长度没有变长,所以只能支持2个双精度浮点计算或是4个单精度浮点计算.另外,它在这组寄存器上实现了整型计算,从而代替了MMX.SSE3支持一些更加复杂的算术计算.SSE4增加了更多指令,并且在数据搬移上下了一番工夫,支持不对齐的数据搬移,增加了super shuffle引擎.

AVX指令

AVX指令集是Sandy Bridge和Larrabee架构下的新指令集。AVX是在之前的128bit扩展到和256bit的SIMD(Single Instruction, Multiple Data)。而Sandy Bridge的SIMD演算单元扩展到256bits的同时数据传输也获得了提升,所以从理论上看CPU内核浮点运算性能提升到了2倍。
Intel AVX指令集,在SIMD计算性能增强的同时也沿用了的MMX/SSE指令集。不过和MMX/SSE的不同点在于增强的AVX指令,从指令的格式上就发生了很大的变化。x86(IA-32/Intel 64)架构的基础上增加了prefix(Prefix),所以实现了新的命令,也使更加复杂的指令得以实现,从而提升了x86 CPU的性能。
以上来自百度百科。

说起AVX来,还有一个有意思的故事。SSE及其后面的进化过程中一直是增加其后面的数字,即SSE2, SSE3, SSE4,按理说下一次进化应该称为SSE5。实际上SSE5是存在的,只不过仅存在于AMD的处理器里。前几代SSE处理器都是Intel先出,然后AMD跟随,然而到SSE4之后,突然AMD先出了SSE5,抢了Intel的先。Intel不能忍,于是SSE5就没了。

2007年8月,AMD抢先宣布了SSE5指令集(之前从SSE到SSE4均为Intel制定),当时表示该指令集将于2009年推出的Bulldozer处理器中采用。但Intel随即表示,不会支持SSE5。转而在2008年3月,Intel宣布了Sandy Bridge微架构(Intel Tick-Tock策略:45nm Nehalem - 32nm Westmere - 32nm Sandy Bridge),其中将引入全新的AVX指令集。4月份,Intel公布了AVX指令集规范,随后开始不断进行更新。
以上来自再见SSE5 AMD宣布支持Intel AVX指令集-AMD,Intel,AVX-驱动之家

根据Dave Christie的说法,AMD在2007年宣布的SSE5指令集主要包括以下几项革新:3操作数指令甚至4操作数指令,置换与条件移动指令,乘加指令以及其他一系列解决现有SSE指令集缺陷的新指令。
而Intel在2008年4月公布的AVX指令集中,同样包含了SSE5指令集的多项新特性,包括3操作数指令/4操作数指令支持,乘加指令以及部分置换指令等,但实现形式与SSE5不同。并且,AVX指令集还加入了一些SSE5中没有的新特性:SIMD浮点指令长度加倍,为旧版SSE指令增加3操作数指令支持,为未来的指令扩展预留大量OpCode空间等。
由于SSE5和AVX指令集功能类似,并且AVX包含更多的优秀特性,因此AMD决定支持AVX指令集,避免让软件开发者因为要面对两套不同指令集而徒增开发难度。
不过,由于AVX指令集的制定权在Intel手中,未来还可能进行修改。AMD只能保证,其首款支持AVX指令集产品支持目前的最新版本:2009年1月发布的AVX第五版规范。并且,FMA乘加指令只支持到2008年8月的AVX第三版规范。

查看系统支持能力

由于SIMD指令有多个版本,每个版本支持的指令集不同。所以如果你的软件要支持更多的CPU,就要在使用SIMD指令之前知道当前指令运行所在的CPU是否支持这条指令。

x86/x86_64 提供了CPUID指令,可以通过这个指令查询当前CPU指令支持SSE指令集情况。

CPUID指令可以用来查询CPU的好多东西,Intel有一个超过100页的文档,专门介绍cpuid这条指令。这里我们仅介绍一下SSE相关的内容,后面如有机会也可以专门介绍一下这条指令。

首先, CPUID指令是从80486开始才有,之前的CPU没有这条指令,当然这个问题大家大可不必担心,因为你能用到486之前的处理器的机会机乎没有,除非你用模拟器去专门模拟这个处理器。

在EFLAGS中的bit 21可以识别CPU是否支持CPUID指令,如下图:
在这里插入图片描述

CPUID指令的使用有点类似于一个函数调用,你传一个参数给CPUID,然后CPUID指令执行后将一些返回值返回给你。你通过EAX寄存器传参数给CPUID指令,CPUID指令执行完后通过EAX, EBX, ECX, EDX返回给你想的数据。

指令示例

乘累加
一个MMX指令来实现乘累加操作是这样的:
在这里插入图片描述

这是一个PMADD指令,后缀WD是word的意思,即操作数长度为word,即16位,在这个示例中,指令完成了两个乘累加操作,结果为两个32位数,放在一个64位寄存器里.示例是城的a0, a1, a2,a3都是16位数.

这个操作的用处可多了,什么FFT啊,DCT呀都用得着.

SSE指令Single-Scalar和Packed-Scalar

SSE指令的控制更加精细,比如说Single Scalar和Packed Scalar的区别.Single Scalar(-ss后缀)乘法中,四组操作数中有一组操作数进行了计算,其他操作数不动.Packed-Scalar(-ps后缀)乘法中,四组操作数都参与计算.
在这里插入图片描述

SIMD指令怎么用?
使用SIMD指令有三种方法,(1)最简单的方法就是我们写C/C++代码,让编译器自己转化。写代码的时候遵守某些规则可以帮助编译器尽量吧。(2)使用编译器提供的intrinsic,即编译器实现了一些内置函数和类型,使用它们的时候,对应的操作会翻译成SIMD指令。(3)写汇编代码或是C语言嵌入汇编代码。

转自:https://zhuanlan.zhihu.com/p/31271788

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值