X86架构下SSE系列指令使用

X86架构下SSE系列指令使用


sse指令集中的指令,一条指令可以实现多项数据运算,即SIMD-Single Instruction Multiple Data。
相关资料可参考:
http://blog.chinaunix.net/uid-20385936-id-3902720.html 
http://blog.youkuaiyun.com/fengbingchun/article/details/18460199 


下面的简短示例代码,函数f1使用sse实现了两个数组的累加:array_c = array_a + array_b;
#include <stdio.h>
#include <emmintrin.h>


int array_a[4] __attribute__ ((aligned (128))) = {1,2,3,4};
int array_b[4] __attribute__ ((aligned (128))) = {3,7,2,1};
int array_c[4] __attribute__ ((aligned (128)));


void f1(void *a, void *b, void *c)
{
    __m128i big1 = _mm_load_si128((__m128i *)(a));
    __m128i big2 = _mm_load_si128((__m128i *)(b));
    __m128i big3 = _mm_add_epi16(big1,big2);
    _mm_store_si128((__m128i *)c,big3);
}


int main()
{
    int i;
    f1(array_a, array_b, array_c);


    for (i=0;i<4;i++)
    {
        printf("%d ", array_c[i]);
    }
    
    return 0;
}




编译运行效果:
# gcc test.c -msse2 -O2 
# ./a.out 
4 9 5 5


再看看函数f1的汇编代码,真是相当简单,3条指令就完成了数组的累加


0000000000400570 <f1>:
<span style="color:#ff0000;">  400570:	66 0f 6f 07          	movdqa (%rdi),%xmm0
  400574:	66 0f fd 06          	paddw  (%rsi),%xmm0
  400578:	66 0f 7f 02          	movdqa %xmm0,(%rdx)</span>
  40057c:	c3                   	retq   
  40057d:	0f 1f 00             	nopl   (%rax)


若要使用SSE指令,需要在编译选项中增加-msse2(或-msse3, 或-msse4),当启用了高版本的的选项时,低版本的选项也就同时自动启用了。
当启用了-msse系列的选项时,编译器就可以编译使用了加速指令的嵌入式汇编代码,也可以针对代码中调用的sse系列的bultin函数(例如int __builtin_ia32_comisdgt (v2df, v2df))生成相应的sse指令代码。
如何让源代码同时适应启用与不启用-msse系列选项的情况呢?
当gcc编译命令中带了-msse系列选项时,会有相应的预定义的宏存在。
通过如下命令,就能知道,启用-msse4时,编译器会预定义哪些sse相关的宏,这就告诉了编码者,当前编译启动了何种sse。
从输出也能看出,启用高级别的sse时,低级别的sse也就自动打开了。
# gcc  -dM  -E  -msse4 - <<<''  | grep SSE
#define __SSE4_1__ 1
#define __SSE4_2__ 1
#define __SSE2_MATH__ 1
#define __SSE_MATH__ 1
#define __SSE2__ 1
#define __SSSE3__ 1
#define __SSE__ 1
#define __SSE3__ 1


如何在代码中使用sse相关指令呢?
要么自己写嵌入式汇编代码,
要么调用相关的builtin函数(不同级别的sse有不同的builtin函数集,这些函数在编译时自动生成sse指令代码),
要么#include <emmintrin.h>并使用其中声明的接口。


通过查看/usr/lib/gcc/x86_64-redhat-linux/4.8.2/include/emmintrin.h的内容,可以发现,这个头文件,实际上是将sse2系列的相关builtin函数进行了包装。这样的话,如果直接使用emmintrin.h中的接口,相当于只能使用到sse2级别的加速指令。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值