一个有目标,为自己的未来努力奋斗的人
分类:
2010-12-04 00:56:48
1、编译器的自动矢量化
-mfpmath=sse
仅建议在P4和K8以上级别的处理器上使用该选项。
-mmmx
-msse
-msse2
-msse3
-m3dnow
-mssse3(gcc-4.3新增)
-msse4.1(gcc-4.3新增)
-msse4.2(gcc-4.3新增)
-msse4(含4.1和4.2,gcc-4.3新增)
是否使用相应的扩展指令集以及内置函数,需要按照自己的cpu做选择。
2、使用C/C++类库
目前,GNU GCC等大多数编译器都提供了对SSE指令集的变成支持,允许用户在C++代码中不用编写汇编代码,就可以直接通过调用库函数而直接使用SSE指令。
3、使用编译器的内嵌原语(Intrinsics)
SSE的intrinsics的规则
_mm_
其中,
ps:Packed Single-precision,指对寄存器中的四个单精度浮点同时进行运算。
ss:Scaler Single-precision,指对寄存器中的DATA0进行运算。
编程时需要包含下表所示的头文件:
mmintrin.h |
MMX |
xmmintrin.h |
SSE |
emmintrin.h |
SSE2 |
pmmintrin.h |
SSE3 |
tmmintrin.h |
SSSE3 |
intrin.h |
SSE4A |
smmintrin.h |
SSE4.1 |
nmmintrin.h |
SSE4.2 |
mm3dnow.h |
3DNOW |
说明:如果导入一个高版本的指令集头文件,那么一般就不需要在导入低版本的指令了。
4、使用内嵌汇编
指令语法特征
如:PADDUSW(无符号饱和模式的字组相加)
前缀:P代表成组数据类型
操作指令:如ADD、SUB等
后缀:US为无符号饱和处理
S为有符号饱和处理
B、W、D、Q分别为字节组、字组、双字组、四字。
GCC的asm结构
用汇编编写的程序运行速度快,但开发速度非常慢,效率也很低。如果只是想对关键代码段进行优化,更好的办法是将汇编指令嵌入到C语言程序中,充分利用高级语言和汇编语言各自的优点。一般来讲,在C代码中嵌入汇编语句要比“纯粹”的汇编语言代码复杂的多,因为需要解决如何分配寄存器,以及如何与C代码中的变量相结合等问题。内联汇编能够灵活操作,而且可以使其输出通过C变量显示出来。因为它具有这种能力,所以asm可以用作汇编指令和C程序之间的接口。使用__asm__关键字,如果超过一行的指令,每行要加上双引号,并且后面加上\n\t。如果希望确保编译器不会在“asm”内部优化指令,可以在“__asm__”后面使用关键字“volatile”。
内联汇编的基本要素
具体语法结构,请看我的一篇博文:《GCC内嵌汇编》文章连接:
http://blog.chinaunix.net/u3/119372/showart_2417924.html
基本要素说明:
限定符 |
意义 |
“m” “v” “o” |
内存单元 |
“r” |
任意寄存器 |
“q” |
寄存器eax,ebx,ecx,edx之一 |
“i” “h” |
直接操作数 |
“E” “F” |
浮点数 |
“g” |
任意 |
“a” ”b” ”c” ”d” |
分别表示寄存器eax,ebx,ecx,edx |
“S” ”D” |
寄存器esi,edi |
“I” |
常数(0至31) |
5、SSE编程注意事项
数据对齐
CPU内存单元以16Byte为边界,如果数据在运算之前不进行对齐,会是指令运算产生大量延时。
GCC:
float __attribute__((aligned(16))) a[4]={1.2f,3.5f,1.7f,2.8f};
VC:
__declspec(align(16)) float a[4]={1.2f,3.5f,1.7f,2.8f};