SSE入门
来源:互联网 发布:网络创新项目 编辑:程序博客网 时间:2024/06/06 06:51
http://blog.csdn.net/bendanban/article/details/42299863
此文主要内容来自这篇文章,本文翻译只求能理解,不求逐句翻译。
正文:
我们将在本文中介绍如何在C++/C中使用SSE指令。我的目的不是用SSE写尽可能快的程序,而是试图讲明白它的使用方法。
什么是SSE?
SSE的全称是 Sreaming SIMD Extensions, 它是一组CPU指令,用于像信号处理、科学计算或者3D图形计算一样的应用。
SIMD 也是几个单词的首写字母组成的: Single Instruction, Multiple Data。 一个指令发出后,同一时刻被放到不同的数据上执行,
这个指令就是SIMD指令。
SSE在1999年首次出现在Pentium 3上。在过去的那段时光里,一些更加精致的功能被加入了这套指令集,
8个128-bit的寄存器被加入了CPU :xmm0到xmm7.
最初的时候,这些寄存器智能用来做单精度浮点数计算(float),
自从SSE2开始,这些寄存器可以被用来计算任何基本数据类型的数据了。
给定一个标准的32位机器,我们可以并行的存储和计算了:
-- 2 double
-- 2 long
-- 4 float
-- 4 int
-- 8 short
-- 16 char
注意:整数类型可以是有符号也可以是无符号的,不过有时候你可能要用不同的指令来处理他们。
比如,你想计算两个整数数组的和,你可以一次计算四个加法。
简单的例子
开始学习SSE并不是很简单的,幸好MSDN的文档写的很好(原作的链接打不开了,新连接是我加上去的)!
如果你看一下那个算术操作的列表,一会注意到总有相应的汇编指令与其对应。
另外,一些操作是符合操作,例如那些set操作。
在C++中用SSE真真是一个low-level的操作:我们将直接通过类型
__m128(4个float)、__m128d(2个double)、__m128i(int、short、char)直接控制那些128-bit的寄存器。
不过,为了使用SSE我们不必去声明__m128类型的数组:比如,你想计算一个浮点型数组中每个元素的平方根,
有可以直接将你的数组强制类型转换成__m128*,然后使用SSE的命令操作这个数组。
不管怎样,我们还是要多做一点事情,才能用SSE。大多数SSE操作需要我们的数据是16-bytes对齐的,
这里我们将使用另一个GCC的 Variable attributes。 我们使用对齐属性:
下面是一个简单的代码,展示如何用SSE的_mm_sqrt_ps()函数一次性计算四个浮点数的平方根:
如果用GCC编译器,在编译选项中加入-S选项,产生的汇编代码中相应的汇编语句是SQRTPS,
而且这个指令使用的寄存器就是SSE的寄存器:
不要忘了加上那个头文件:
第一个评测
在前面的代码中,我们同时计算了4个float的平方根,但是我们没有记录结果。为了记录结果,我们使用_mm_store_ps
在下面的代码中,我们计算一个非常大的float数组的平方根。(作者使用的是他之前写的计时函数,这里我直接贴出来了)
来对程序的标准版本和SSE版计时。
在上面的SSE的函数代码中,我们用了两个指针指向的是同一个地址,但是使用的类型不同,这当然不是必须的,只是用来避免强制类型转换。
有趣的是,我们必须对__m128每次递增1(128bits),对应的,我们也必须按四递增float指针(就是相当于一次算四个float)。
另一个有趣的函数式 posix_memalign,而不是用align attribute,这个函数是在堆上申请对齐内存,而gcc attribute是在栈上申请内存。
评测环境: llvm-g++ 4.2 (flags: -O3 -msse2) 在Intel Core2 Duo P7350(2GHz)上测试。
真的相当快哈!
第二个评测
怎么将两个char数据加在一起呢:
评测结果:
性能分析
你可能会问,为什么我们没有得到四倍的加速呢?我们可是一次计算4个float数据啊,怎么我们只有2倍的加速呢??
答案是,你的编译器很聪明,它已经做了很多优化了,特别是在加入O3选项后。
实际上,如果你看下normal产生的汇编代码,里面的sqrt和add函数都已经被你的编译器给用SSE指令优化了。
编译器检测到循环模式适合SSE,就把这个代码使用SSE指令实现了。
不管怎样,直接使用SSE函数还是可以获得一些性能的。
取决于你的编译器版本,对于这种简单的循环,你发现执行时间上没有差异也是可能的。
但是,这里必须要再提一次的是,我们是介绍怎么用SSE,不是只为了性能~
- sse 入门
- SSE入门
- SSE 入门
- SSE入门
- SSE指令集入门
- SSE指令集入门
- SSE指令集入门
- SSE指令集入门
- SSE指令集简单入门
- SSE
- SSE
- SSE
- SSE指令算法及应用----入门篇
- SSE 介紹
- SSE 介紹
- SSE介绍
- Install SSE
- SSE Instructions
- drawable下的圆角背景XML
- 分享Kali Linux 2016.2第48周虚拟机
- Android版本更新完毕自动开启APP应用
- 自定义控件(29)---onTouchEvent与Scroller
- YOLO:You Only Look Once 论文阅读
- SSE入门
- CAFFE 编译成功了
- 比较好的js资源站
- gabor小波滤波器的在纹理提取、图像匹配上的作用
- 继承object对象对python多继承的影响
- iOS 10 开发适配系列 之 权限Crash问题
- Java设计模式之迭代子模式
- spring security3 demo入门
- 携程是如何借助“预测式外呼”提高呼叫效率的