使用MMX/SSE汇编指令集优化视频开发

1、汇编指令集


目前大部分的PC机采用的都是Intel或者AMD的CPU,其支持的多媒体汇编指令有:

  1. MMX:多媒体扩展指令(MultiMedia eXtention),该指令由Intel在1996年为Pentium处理器开发,包括了57条多媒体指令,可以i一次处理多个数据。但是MMX指令不能与X86浮点运算指令同时执行,在某些场合使用受到一定限制。
  2. SSE:SIMD扩展指令集(Streaming SIMD Extension),也称作单指令多数据流扩展。其中的SIMD的含义为Single Instruction Multiple Data(单指令多数据)。该指令集有Intel为Pentium III研发,是为了提高处理浮点运算性能而开发的指令集,有70条指令,包括50条SIMD浮点运算指令用于提升3D图形运算效率、12条MMX整数运算增强指令和8条优化内存中连续数据块传输指令。这些指令有利于优化图像处理、浮点运算、3D运算和多媒体处理等运算的性能。
  3. 3DNow!:3DNow!指令集由AMD开发,有21条扩展指令。3DNow!指令集主要针对三维建模、坐标变换和效果渲染等3D数据处理。
  4. SSE2:SSE2指令集是比SSE更加先进的指令集,共包含144条指令,由两个部分组成:SSE主要负责处理浮点数,MMX主要负责处理整数计算。SSE2的寄存器容量是MMX的两倍,寄存器存储的数据也是MMX的两倍。SSE2可以向下兼容MMX,经由MMX进行优化的程序可以继续由SSE2进行进一步的优化。
  5. SSE3:SSE3是在SSE2的基础上开发的,相比SSE2增加了13个SIMD指令,主要目的在于改进线进程同步和媒体、游戏等特殊应用程序领域。其中定义了超线程性能增强作为其中的一部分,可以提升处理器的超线程处理能力,使得处理器更快地进行并行数据处理。
  6. SSE4:SSE4是Intel自SSE2以来最大的改进,包括了从多媒体应用到高性能计算领域的应用,以及使用一些专用电路进行特定应用的加速。SSE4增加了47条指令,改进了整数型和浮点型计算、支持DWORD和QWORD操作、新的单精度FP操作、快速寄存器操作和面向寄存器的内存操作等。


2、MMX/SSE2指令集剖析


2.1、媒体扩展指令MMX

Intel的MMX指令是Intel IA系列指令的扩展,使用了单指令多数据技术(SIMD),以并行方式处理多个数据元素。MMX扩展指令集新增了57条指令和一种64位的4字数据,作为成组的数据可供MMX指令操作。一个64位数据类型可以包含8个字节、4个字、两个双字或者一个4重字类型,这样一条MMX指令即可以同时处理2/4/8个数据单元。为了适应这样的数据,MMX增加了8个64位寄存器(MM0~MM7),仅有MMX指令可以按寄存器名称直接访问。

MMX针对8~32位数据元素的处理性能进行了改善,一个MMX指令可以处理8个字节,一个时钟周期内完成两条指令,即一个时钟周期可以处理16个字节。此外,MMX技术为其他功能释放了额外的处理器周期,更小的处理器占用率可以实现更高程度的并发。

一、MMX指令集简介:

MMX指令集从功能上可以分为8类:数据传送指令、算术运算指令、比较运算指令、类型转换指令、扩展压缩数据指令、逻辑运算指令、移位运算指令、状态清除指令。指令列表如下:

使用MMX/SSE汇编指令集优化视频开发_第1张图片

使用MMX/SSE汇编指令集优化视频开发_第2张图片

在以上指令中,除了EMMS指令外,都涉及两个操作数,即源操作数和目标操作数,指令中源操作数在右,目标操作数在左。目标操作数可作为第二个源操作数进行操作,指令结束后被运算结果所覆盖

1)、数据转移指令:

数据转移指令实现MMX寄存器同内存单元之间,以及MMX寄存器同通用寄存器之间的双向数据传递功能。

MOVD:转移32位(4字节)数据;MOVQ:转移64位(8字节)数据。


2)、算数运算指令:

算数运算指令对打包的数据类型实现加法、减法、乘法和乘加操作。

在介绍算术运算指令前,先简要介绍一下所谓的“环绕模式”和“饱和模式”。所谓环绕模式,就是当一个数据单元的数据达到最大值(比如一个字节的值为255)时,如果继续对其加1,那么该字节的数据将变为0,进位将被忽略。饱和模式则对数据的溢出进行了限制,根据有符号或者无符号类型,将运算后的结果限制在数据类型规定的范围以内。

  • PADDB/PADDW/PADDD和PSUBB/PSUBW/PSUBD指令分别在环绕模式下对源和目标操作数进行有符号或无符号的相加和相减操作。每一组的三个指令分别对应字节型、字形和双字型数据。
  • PADDSB/PADDSW和PSUBSB/PSUBSW指令分别在有符号饱和模式下进行相加和相减操作。两个指令分别处理字节型和字型数据。
  • PADDUSB/PADDUSW和PSUBUSB/PSUBUSW指令分别在无符号饱和模式下进行相加和相减操作。两个指令分别处理字节型和字型数据。
  • PMULHW和PMULLW指令执行源和目标操作数的乘法操作,并分别将乘积的高字和低字保存到目标操作数中。
  • PMADDWD指令计算源和目标操作数有符号部分的乘积,并将产生的4个32位双字的中间结果成对相加,获得两个32位双字。

PMADDWD的计算结果如图示显示:

使用MMX/SSE汇编指令集优化视频开发_第3张图片


3).比较指令:

PCMPEQB/PCMPEQW/PCMPEQD和PCMPGTB/PCMPGTW/PCMPGTD指令按照有符号类型数据比较源和目标操作数进行相等比较或大于比较。对于相等比较,如果一对数据元素相等,则目标操作数中的相应数据元素设置为全 1;否则设置为全 0。对于大于比较,如果目标操作数中的数据元素大于源操作数中相应的数据元素,则目标操作数中的相应数据元素设置为全 1;否则设置为全 0。


4).类型转换指令:

PACKSSWB指令将有符号字转换成为有符号的字节;PACKSSDW将有符号的双字转换成为有符号的字;转换过程都按照有符号饱和模式进行。

PACKUSWB指令将有符号的字转换为无符号的字节,转换过程按照无符号饱和模式进行。

5).扩展压缩数据指令:

PUNPCKHBW/PUNPCKHWD/PUNPCKHDQ指令和PUNPCKLBW/PUNPCKLWD/PUNPCKLDQ分别将源于目标操作数的高位数据和低位数据取出并交错排入目标操作数中。PUNPCKHBW和PUNPCKLBW的示意图如下:

使用MMX/SSE汇编指令集优化视频开发_第4张图片

PUNPCKHBW操作示意图

使用MMX/SSE汇编指令集优化视频开发_第5张图片

PUNPCKLBW操作示意图


6).逻辑运算指令:

PAND——逻辑按位与;PANDN——逻辑按位与非;POR——逻辑按位或;PXOR——逻辑按位或非;


7).位移指令:

位移指令有逻辑左移、逻辑右移和算数右移三种。

PSLLW/PSLLD/PSLLQ和PSRLW/PSRLD/PSRLQ实现逻辑左移和右移操作,并用0填充空出来的高位或低位。支持字型、双字型和四字型数据;PSRAW/PSRAD实现算数右移操作,并将符号位拷贝到右移所空出的比特位上。


8).状态清除指令:

EMMS指令用于将MMX状态清空。该指令在一个MMX程序结束时执行。


二、CPU寄存器

除了8个MMX寄存器之外,CPU还有自己的通用寄存器EAX/EBX/ECX/EDX。这四个通用寄存器都是32位寄存器,可以直接访问,还可以按照16位和8位进行访问。如EAX可以使用AX获得低16位,AX可以使用AH和AL分别获取高8位和低8位。其余的寄存器有ESI/EDI/ESP/EBP等。功能描述见下图:

使用MMX/SSE汇编指令集优化视频开发_第6张图片


三、地址加载指令

1).LEA指令

LEA指令将源操作数的偏移地址传递给通用寄存器。如以下代码:

LEA BX, [2400H]
该指令将[2400H]的偏移地址2400传送给BX,执行后BX=2400H。

2).LDS指令

LDS指令将4字节源内存的数据按照段地址和偏移地址传送给链各个寄存器,其中低地址的2字节作为偏移地址送给作为目标操作数的寄存器,高地址的2字节作为段地址送到DS寄存器。如以下代码:

LDS DI, [2130H]
该指令将低地址2130H、2131H的数据作为偏移地址送到DI中,2132H、2133H的数据作为段地址送到DS中。


2.2、MMX程序设计

使用MMX编程的方法主要有三种:

  • 直接编写汇编程序文件,命名为*.asm;
  • 使用C++嵌入汇编,在C++代码中使用__asm{....}编写汇编程序;
  • 使用64位数据类型__m64和与MMX相关的C++函数实现。


2.3、SSE/SSE2媒体扩展指令集

SSE和SSE2是基于MMX的新的汇编指令集,将寄存器的大小从64位扩展到128位,且增加了新的媒体处理汇编指令。

一、SSE/SSE2数据结构

SSE技术支持打包的单精度浮点数操作(Packed Single-Precision Floating-point),将4个独立的32位单精度浮点数打包为一个128位数据。SSE提供了8个128位SIMD寄存器XMM0~XMM7,可以直接存取,但只能存放数据而不能用于寻址。此外SSE还提供了新的控制/状态寄存器MXCSR。

SSE2指令包括原油的32位通用寄存器(EAX~EDX)、64位MMX寄存器(MM0~MM7)、128位XMM(XMM0~XMM7)和32位标识寄存器EFLAGS及浮点状态/控制寄存器MCSR。此外还有两种数据类型:128位的打包双精度浮点数和4种128位SIMD整数。

  • 128位打包双精度浮点数:两个64位双精度浮点数打包成一个双4字节数据;
  • 128位打包整数:可以包含16个字节、8个字、4个双字或2个四重字的整数;

二、SSE/SSE/2指令

SSE指令集包含70条指令,主要可以分为三组:

  1. 50条SIMD浮点运算指令:50条SIMD浮点运算指令是其主要部分,包括几个部分:数据传送指令、算数运算指令、比较指令、类型转换指令、组合指令、状态管理指令。
  2. 12条SIMD整数指令:为了增强MMX指令系统而新增。
  3. 8条高速缓冲存储器优化指令:8条指令,为更好滴控制缓存操作,提供啊程序运行性能,专门针对Pentium III设计。

SSE2指令集主要包括针对128位和64位的打包双精度浮点计算指令,记忆64位和128位的SIMD整数指令、MMX/SSE的128位扩展指令、高速缓存控制盒指令排序指令。

  1. SSE2浮点计算指令:SSE2浮点运算指令分为多组,主要有SSE2的传送指令、算术运算指令、逻辑运算指令、比较指令、组合指令和转换指令等。
  2. SSE2扩展指令:除双精度浮点指令外,在原油的MMX和SSE基础上补充了SIMD扩展整数指令、高速缓存控制和指令排序指令。

你可能感兴趣的:(汇编语言)