SSE(即Streaming SIMD Extension),是对由MMX指令集引进的SIMD模型的扩展。我们知道MMX有两个明显的缺点:

  • 只能操作整数。
  • 不能与浮点数同时运行(MMX使用FPU寄存器作为别名)。

而SSE则解决了这个问题,SSE引进了8个专用的浮点寄存器MMX0~MMX7。后来Intel又陆续推出了SSE2、SSE3、SSE4,这使得SSE指令系列同时拥有了浮点数学运算功能和整数运算功能,因此早先的MMX指令就显得有点多余了(虽然可是并行执行SSE、MMX指令来提高性能)。

SSE系列功能特点

SSE1

  • 添加8个128位寄存器XMM0~MMX7.
  • 操作4个单精度浮点数。
  • 支持打包(Packed)标量(Scaler)操作。

SSE2

  • 添加整数向量运算,提升运行性能。
  • 支持双精度浮点向量运算。
  • 打包类型取消限制,支持8位、16位、32位、64位,包括整数和浮点数。
  • 添加缓存控制指令
  • 添加浮点数到整数的转换指令

SSE3

  • 寄存器内水平操作,例如打包在一个128位MMX寄存器内的2个64位整数,可以利用新指令对这两个整数进行算数运算。
  • 多线程优化指令,在超线程下提高性能。

SSSE3

  • 打包整形数据的运算加速

SSE4

SSE4包含两个子集:SSE4.1和SSE4.2,并兼容以前的64位和IA-32指令集架构。值得指出的是SSE4增加了:1)STTNI(String and Text New Instructions)指令来帮助开发者处理字符搜索和比较,旨在加速对XML文件的解析;2)CRC32指令,帮助计算循环冗余校验值

SSE效率对比

这里我们就只简单比较下这两个指令集的计算效率,其他功能就不在本次考虑范围内了。像前一篇博客一样,我们同样用对10000000个字符进行加操作来进行对比操作。这里我们全部用Intrinsics来对比,方便编写,不用考虑调用约定。

整数计算 Mmx vs Sse

因为整数操作只在SSE2中支持,所以实际上我们用的是sse2指令。

mmx代码:

void calculateUsingMmx(char* data, unsigned size)
{
assert(size % 8 == 0); __m64 step = _mm_set_pi8(10, 10, 10, 10, 10, 10, 10, 10);
__m64* dst = reinterpret_cast<__m64*>(data);
for (unsigned i = 0; i < size; i += 8)
{
auto sum = _mm_adds_pi8(step, *dst);
*dst++ = sum;
} _mm_empty();
}

sse代码:

void calculateUsingSseInt(char* data, unsigned size)
{
assert(size % 16 == 0); __m128i step = _mm_set_epi8(10, 10, 10, 10, 10, 10, 10, 10,
10, 10, 10, 10, 10, 10, 10, 10);
__m128i* dst = reinterpret_cast<__m128i*>(data);
for (unsigned i = 0; i < size; i += 16)
{
auto sum = _mm_add_epi8(step, *dst);
*dst++ = sum;
} // no need to clear flags like mmx because SSE and FPU can be used at the same time.
}

浮点计算 Asm vs Sse

由于MMX指令集不包含浮点指令,因此我们x86浮点指令来对比,同样对10000000个flaot值进行加操作。

Asm代码:

void calculateUsingAsmFloat(float* data, unsigned count)
{
auto singleFloatBytes = sizeof(float);
auto step = 10.0;
__asm
{
push ecx
push edx mov edx, data
mov ecx, count
fld step // fld only accept FPU or Memory calcLoop:
fld [edx]
fadd st(0), st(1)
fstp [edx]
add edx, singleFloatBytes
dec ecx
jnz calcLoop pop edx
pop ecx
}
}

Sse代码:

void calculateUsingSseFloat(float* data, unsigned count)
{
assert(count % 4 == 0);
assert(sizeof(float) == 4); __m128 step = _mm_set_ps(10.0, 10.0, 10.0, 10.0);
__m128* dst = reinterpret_cast<__m128*>(data);
for (unsigned i = 0; i < count; i += 4)
{
__m128 sum = _mm_add_ps(step, *dst);
*dst++ = sum;
}
}

运行结果

SSE2的浮点计算对比x86浮点计算性能提升不是非常明显,但是也要考虑Intrinsics使用导致的略微性能缺失。上面两种计算方式的效率对比结果如下:

完整代码见链接

SIMD---SSE系列及效率对比的更多相关文章

  1. string中Insert与Format效率对比、String与List中Contains与IndexOf的效率对比

    关于string的效率,众所周知的恐怕是“+”和StringBuilder了,这些本文就不在赘述了.关于本文,请先回答以下问题(假设都是基于多次循环反复调用的情况下):1.使用Insert与Forma ...

  2. FileInputStream 与 BufferedInputStream 效率对比

    我的技术博客经常被流氓网站恶意爬取转载.请移步原文:http://www.cnblogs.com/hamhog/p/3550158.html ,享受整齐的排版.有效的链接.正确的代码缩进.更好的阅读体 ...

  3. SSE 系列内置函数中的 shuffle 函数

    SSE 系列内置函数中的 shuffle 函数 邮箱: quarrying@qq.com 博客: http://www.cnblogs.com/quarryman/ 发布时间: 2017年04月18日 ...

  4. java中多种写文件方式的效率对比实验

    一.实验背景 最近在考虑一个问题:“如果快速地向文件中写入数据”,java提供了多种文件写入的方式,效率上各有异同,基本上可以分为如下三大类:字节流输出.字符流输出.内存文件映射输出.前两种又可以分为 ...

  5. golang 浮点数 取精度的效率对比

    需求 浮点数取2位精度输出 实现 代码 package main import ( "time" "log" "strconv" " ...

  6. Snapman系统中TCC执行效率和C#执行效率对比

    Snapman集合了TCC编译器可以直接编译执行C语言脚本,其脚本执行效率和C#编译程序进行效率对比,包括下面4方面: 1.函数执行效率 2.数字转换成字符串 3.字符串的叠加 4.MD5算法 这是C ...

  7. 查询最新记录的sql语句效率对比

    在工作中,我们经常需要检索出最新条数据,能够实现该功能的sql语句很多,下面列举三个进行效率对比 本次实验的数据表中有55万条数据,以myql为例: 方式1: SELECT * FROM t_devi ...

  8. c#中@标志的作用 C#通过序列化实现深表复制 细说并发编程-TPL 大数据量下DataTable To List效率对比 【转载】C#工具类:实现文件操作File的工具类 异步多线程 Async .net 多线程 Thread ThreadPool Task .Net 反射学习

    c#中@标志的作用   参考微软官方文档-特殊字符@,地址 https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/toke ...

  9. EF 数据查询效率对比

    优化的地方: 原地址:https://www.cnblogs.com/yaopengfei/p/9226328.html ①:如果仅是查询数据,并不对数据进行增.删.改操作,查询数据的时候可以取消状态 ...

随机推荐

  1. Jetty添加Filter过滤器

    1.Jetty嵌入到Spring项目 try { Server server = new Server(8080); WebAppContext context = new WebAppContext ...

  2. eclipse快捷键及设置

    1.Eclipse设置新建菜单初始项 windows-->Perspective-->Customize Perspective--> 2.Eclipse快捷键 1. ctrl+sh ...

  3. mysql打不开表问题解决方案

    做开发时候某一表怎么也打不开,数据也不多,网上查了按下面这篇文章完美解决,但是要记得用root登录mysql: 记一次MySQL中Waiting for table metadata lock的解决方 ...

  4. Shell脚本编程学习入门 02

    Shell脚本编程学习入门是本文要介绍的内容,我们可以使用任意一种文字编辑器,比如gedit.kedit.emacs.vi等来编写shell脚本,它必须以如下行开始(必须放在文件的第一行):   #! ...

  5. List转换成JSON对象报错(三)

    List转换成JSON对象 1.具体错误如下 Exception in thread "main" java.lang.NoClassDefFoundError: net/sf/e ...

  6. ucos-ii的任务调度机制

    1.在ucos-ii中,有这么几张表来管理任务. A.OSTCBPrioTbl[],其结构为OS_TCB指针的数组,其元素个数为64, 每一个元素对应一个任务的优先级,ucos-ii最多可以有64个任 ...

  7. Java和Flex整合报错(一)

    1.错误描述 at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(Def ...

  8. web开发性能优化---代码优化篇

    1.合理使用缓存使用 提高性能最好最快的办法当然是通过缓存来改善,对于任何一个web开发者都应该善用缓存.Asp.net下的缓存机制十分强大,用好缓存机制可以让我们极大的改善web应用的性能. 1.页 ...

  9. SQL Server 2008 R2 添加登录账户配置权限

    一.新建登录名1. 在登录名右侧的文本框中输入新建的管理员账号名称:2. 一对单选按钮组中,选择Sql Server 身份验证,并输入登录密码:3. 勾选强制实施密码策略复选框:(密码策略一般是指加强 ...

  10. DBUtils-对JDBC简单封装的开源工具类库

    DBUtils 是对JDBC简单封装的开源工具类 详细介绍地址:  https://baike.baidu.com/item/Dbutils/10655914?fr=aladdin 在使用DBUtil ...