SSE2介绍及其简单用法举例

SSE2,全名为Streaming SIMD Extensions 2,是一种IA-32架构的SIMD指令集。SSE2是在2001随着Intel发表第一代Pentium 4处理器也一并推出的指令集。它延伸较早的SSE指令集,而且可以完全取代MMX指令集。在2004,Intel再度扩展了SSE2指令为SSE3指令集。与70条指令的SSE相比,SSE2 新增了144条指令。在2003AMD也在发布AMD64的64比特处理器时跟进SSE2指令集。

SSE2延伸了MMX指令群使用XMM暂存器来运算,这能让开发人员完全避免让8个64比特MMX暂存器与原有的IA-32浮点运算暂存器共用。而这样子就能够不需要切换MMX与x87浮点运算的前提之下混合SIMD标量与浮点矢量运算。不过,这不会因为SSE的暂存器的精度提高而让运算结果的精度也提高。而还有部分的SSE2指令集包含了一系列的CPU高速缓存控制指令。当处理理论上无限的数据流,还有数字格式转换指令所产生出来的大量补数,能够使高速缓存污染有效的降低。AMD在AMD64架构上的SSE2再新增额外8个暂存器,把暂存器的量提升到16个(XMM0~XMM15)。这些额外的暂存器只有运行于64比特的模式下才能够使用。2004年,Intel也采用这些额外的暂存器于它的x86-64(Intel 64)架构。

    MMX与SSE2的差别:SSE2让MMX指令群使用XMM暂存器来运算。换句话说,现有的MMX脚本能够完全转换成SSE2。不过XMM的暂存器是MMX暂存器的两倍大,循环计数器与存储器访问机制也会跟着修改来因此变化。而即使一个SSE2指令能够比MMX指令操作多两倍数据量,性能也并没有很明显的提升。有两个主要原因导致此现象:存储器内部访问SSE2的数据并没有以16字节的间隔对齐,这会造成明显的性能损失。还有在大多数的x86架构实现上SSE2的指令吞吐量是小于MMX的。Intel 首先面对第一个问题的解决方案是在SSE3指令中新增一个指令,能够在处理未对齐的数据时减少overhead。而第二个问题也在Core微架构中将运行引擎加宽而解决。

    支持SSE2的编译器:(1)、微软的Visual C++与MASM;(2)、Intel C++ 编译器;(3)、GCC 3及更高版本;(4)、Sun Studio Compiler Suite。

支持SSE2指令集的处理器:(1)、Athlon 64Sempron 64Turion 64 等为主的 AMD K8 架构处理器;(2)、PhenomPhenom IIAthlon II 等为主的 AMD K10AMDK10.5 架构处理器;(3)、Pentium 4XeonCeleronCeleron D 等为主的 Intel NetBurst 架构的处理器;(4)、Intel Pentium M 与 Celeron M;(5)、Intel Core 架构的处理器,包括 Core Duo、Core Solo 等;(6)、IntelCore 2 架构的处理器,包含 Core 2 Duo、Core 2 Quad、Core 2 Extreme 等;(7)、Intel Core i3Core i5Core i7 等;(8)、Intel Atom;(9)、Transmeta(全美达)Efficeon;(10)、VIA(威盛)C7;(11)、VIA Nano

    不支持SSE2处理器的共同特点:SSE2是IA-32架构的延伸。所以目前所有不支持IA-32架构的其他架构一概不支持SSE2。由于x86-64架构的处理器是由IA-32延伸出来的,所有x86-64架构的处理器也都支持SSE2指令集。而有些CPU并没有支持SSE2,但是有其他的指令集可以提供与SSE2相似的功能。下列的IA-32架构的处理器是在SSE2 发表之后才开发的,但是并不支持SSE2指令集:(1)、比 Athlon 64 早推出的 AMD 处理器,包含了所有使用Socket A插槽的处理器;(2)、比Pentium 4早推出的Intel处理器;(3)、VIA的C3处理器;(4)、Transmeta Crusoe处理器。

SSE2 是一套由越来越多的第三方应用和驱动程序使用的关于处理器的标准指令集。

    SSE2 was first introduced on the IntelPentium 4, and are also known sometimes as "Willamette" instructions.These instructions are very similar to the SSE instructions in structure, butallow us considerably more flexibility in crunching numbers. The biggestdifferences between SSE and SSE2 were the ability to deal withdouble-precision, or 64bit, floating-point values as well as with 32bit ones,along with the ability to now work on 128bit integer types in XMM registers aswell. In total, 144 new instructions were added.

简单用法举例:

#include "stdafx.h"
//#include <mmintrin.h>//mmx header file
//#include <xmmintrin.h>//sse header file(include mmx header file)
#include <emmintrin.h>//sse2 header file(include sse header file)

void Integer_Add(const unsigned char* p1, const unsigned char* p2, unsigned char* p3, int num)
{
	__m128i m1 = _mm_loadu_si128((__m128i*)p1);
	__m128i m2 = _mm_loadu_si128((__m128i*)p2);
	__m128i m3 = _mm_add_epi8(m1, m2);

	_mm_storeu_si128((__m128i*)p3, m3);
}

void Integer_Sub(const unsigned char* p1, const unsigned char* p2, unsigned char* p3, int num)
{
	__m128i m1 = _mm_loadu_si128((__m128i*)p1);
	__m128i m2 = _mm_loadu_si128((__m128i*)p2);
	__m128i m3;

	m3 = _mm_setzero_si128();
	m3 = _mm_subs_epi8(m1, m2);

	_mm_storeu_si128((__m128i*)p3, m3);
}

void Integer_Avg(const unsigned char* p1, const unsigned char* p2, unsigned char* p3, int num)
{
	__m128i m1 = _mm_loadu_si128((__m128i*)p1);
	__m128i m2 = _mm_loadu_si128((__m128i*)p2);
	__m128i m3;

	m3 = _mm_setzero_si128();
	m3 = _mm_avg_epu8(m1, m2);

	_mm_storeu_si128((__m128i*)p3, m3);
}

int _tmain(int argc, _TCHAR* argv[])
{
	const int num = 16;
	unsigned char array1[num] = {0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0};
	unsigned char array2[num] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
	unsigned char array3[num] = {0};

	Integer_Add(array1, array2, array3, num);
	Integer_Sub(array1, array2, array3, num);
	Integer_Avg(array1, array2, array3, num);

	return 0;
}


参考文献:

1、 http://blog.csdn.net/fengbingchun/article/details/18318065

2、http://blog.csdn.net/fengbingchun/article/details/18460199

3、http://zh.wikipedia.org/wiki/SSE2

4、http://blog.csdn.net/zyl910/article/details/8116560

5、http://www.songho.ca/misc/sse/sse.html

6、http://zerocool.is-a-geek.net/?p=422

7、http://courses.engr.illinois.edu/ece390/books/labmanual/inst-ref-simd.html

8、https://www.kernel.org/pub/linux/kernel/people/geoff/cell/ps3-linux-docs/CellProgrammingTutorial/BasicsOfSIMDProgramming.html



SSE2介绍及其简单用法举例

上一篇:OLAT使用问题


下一篇:Android OpenCV实现人脸检测(二)