SSE(Streaming SIMD Extensions)是英特尔在AMD的3D Now!发布一年之后,在其计算机芯片Pentium III中引入的指令集,是MMX的超集。AMD后来在Athlon XP中加入了对这个指令集的支持。这个指令集增加了对8个128位寄存器XMM0-XMM7的支持,每个寄存器可以存储4个单精度浮点数。使用这些寄存器的程序必须使用FXSAVE和FXRSTR指令来保持和恢复状态。但是在Pentium III对SSE的实现中,浮点数寄存器又一次被新的指令集占用了,但是这一次切换运算模式不是必要的了,只是SSE和浮点数指令不能同时进入CPU的处理线而已。

库文件说明

#ifndef __METHOD
#define __METHODvoid ScaleValue1(float *pArray, DWORD dwCount, float fScale);//乘法
void ScaleValue2(float *pArray, DWORD dwCount, float fScale);void Add1(float *pArray, DWORD dwCount, float fScale);//加法
void Add2(float *pArray, DWORD dwCount, float fScale);void Sqrt1(float *pArray, DWORD dwCount, float fScale);//平方
void Sqrt2(float *pArray, DWORD dwCount, float fScale);void Min1(float *pArray, DWORD dwCount, float fScale);//最小值
void Min2(float *pArray, DWORD dwCount, float fScale);//最小值void Max1(float *pArray, DWORD dwCount, float fScale);//最小值
void Max2(float *pArray, DWORD dwCount, float fScale);//最小值void And1(float *pArray, DWORD dwCount, float fScale);//与操作
void And2(float *pArray, DWORD dwCount, float fScale);//与操作#endif
#include <xmmintrin.h>
#include <Windows.h>
#include <math.h>void ScaleValue1(float *pArray, DWORD dwCount, float fScale)//乘法
{DWORD dwGroupCount = dwCount/4;__m128 e_Scale = _mm_set_ps1(fScale);//设置所有4个值为同一值for (DWORD i=0; i<dwGroupCount; i++){*(__m128*)(pArray + i*4) = _mm_mul_ps( *(__m128*)(pArray + i*4),e_Scale);}
}void ScaleValue2(float *pArray, DWORD dwCount, float fScale)
{for (DWORD i =0; i<dwCount; i++){pArray[i] *= fScale;}
}void Add1(float *pArray, DWORD dwCount, float fScale)//加法
{DWORD dwGroupCount = dwCount/4;__m128 e_Scale = _mm_set_ps1(fScale);//设置所有4个值为同一值for (DWORD i=0; i<dwGroupCount; i++){*(__m128*)(pArray + i*4) = _mm_add_ps( *(__m128*)(pArray + i*4),e_Scale);}
}void Add2(float *pArray, DWORD dwCount, float fScale)
{for (DWORD i =0; i<dwCount; i++){pArray[i] += fScale;}
}void Sqrt1(float *pArray, DWORD dwCount, float fScale)//平方
{DWORD dwGroupCount = dwCount/4;__m128 e_Scale = _mm_set_ps1(fScale);//设置所有4个值为同一值for (DWORD i=0; i<dwGroupCount; i++){*(__m128*)(pArray + i*4) = _mm_sqrt_ps(e_Scale);}
}void Sqrt2(float *pArray, DWORD dwCount, float fScale)
{for (DWORD i =0; i<dwCount; i++){pArray[i] = sqrt(fScale);}
}void Min1(float *pArray, DWORD dwCount, float fScale)//最小值
{DWORD dwGroupCount = dwCount/4;__m128 e_Scale = _mm_set_ps1(fScale);//设置所有4个值为同一值for (DWORD i=0; i<dwGroupCount; i++){*(__m128*)(pArray + i*4) = _mm_min_ps( *(__m128*)(pArray + i*4),e_Scale);}
}void Min2(float *pArray, DWORD dwCount, float fScale)
{for (DWORD i =0; i<dwCount; i++){pArray[i] = (pArray[i]>fScale? fScale : pArray[i]);}
}void Max1(float *pArray, DWORD dwCount, float fScale)//最大值
{DWORD dwGroupCount = dwCount/4;__m128 e_Scale = _mm_set_ps1(fScale);//设置所有4个值为同一值for (DWORD i=0; i<dwGroupCount; i++){*(__m128*)(pArray + i*4) = _mm_max_ps( *(__m128*)(pArray + i*4),e_Scale);}
}void Max2(float *pArray, DWORD dwCount, float fScale)
{for (DWORD i =0; i<dwCount; i++){pArray[i] = (pArray[i]<fScale? fScale : pArray[i]);}
}void And1(float *pArray, DWORD dwCount, float fScale)//与操作
{DWORD dwGroupCount = dwCount/4;__m128 e_Scale = _mm_set_ps1(fScale);//设置所有4个值为同一值for (DWORD i=0; i<dwGroupCount; i++){*(__m128*)(pArray + i*4) = _mm_and_ps( *(__m128*)(pArray + i*4),e_Scale);}
}void And2(float *pArray, DWORD dwCount, float fScale)
{for (DWORD i =0; i<dwCount; i++){pArray[i] = (int)(pArray[i]) & (int)(fScale);}
}

采用SSE和不采用SSE的数学计算操作速度对比:

#include <xmmintrin.h>
#include <Windows.h>
#include <iostream>#include "Method.h"using namespace std;#define ARRAYCOUNT 1000#define COUNTSIZE 10000class CTimer
{
public:__forceinline CTimer(void){QueryPerformanceFrequency(&m_Frequency);// 获取时钟周期QueryPerformanceCounter(&m_StartCount);// 获取时钟计数}__forceinline void Reset(void){QueryPerformanceCounter(&m_StartCount);}__forceinline double End(void){QueryPerformanceCounter(&m_EndCount);return ( m_EndCount.QuadPart - m_StartCount.QuadPart )*1000/m_Frequency.QuadPart;}private:LARGE_INTEGER m_Frequency;LARGE_INTEGER m_StartCount;LARGE_INTEGER m_EndCount;
};int __cdecl main()
{float __declspec(align(16))Array[ARRAYCOUNT];//__declspec(align(16))做为数组定义的修释符,这表示该数组是以16字节为边界对齐的,//因为SSE指令只能支持这种格式的内存数据memset(Array, 0, sizeof(float)*ARRAYCOUNT);CTimer t;double dTime;//乘法cout<<"乘法:"<<endl;t.Reset();for (int i=0; i<COUNTSIZE; i++){ScaleValue1(Array, ARRAYCOUNT, 1000.0f);}dTime = t.End();cout<<"Use SSE: "<<dTime<<"毫秒"<<endl;t.Reset();for (int i=0; i<COUNTSIZE; i++){ScaleValue2(Array, ARRAYCOUNT, 1000.0f);}dTime = t.End();cout<<"Not Use SSE: "<<dTime<<"毫秒"<<endl;//加法cout<<"加法:"<<endl;t.Reset();for (int i=0; i<COUNTSIZE; i++){Add1(Array, ARRAYCOUNT, 1000.0f);}dTime = t.End();cout<<"Use SSE: "<<dTime<<"毫秒"<<endl;t.Reset();for (int i=0; i<COUNTSIZE; i++){Add2(Array, ARRAYCOUNT, 1000.0f);}dTime = t.End();cout<<"Not Use SSE: "<<dTime<<"毫秒"<<endl;//平方cout<<"平方:"<<endl;t.Reset();for (int i=0; i<COUNTSIZE; i++){Sqrt1(Array, ARRAYCOUNT, 1000.0f);}dTime = t.End();cout<<"Use SSE: "<<dTime<<"毫秒"<<endl;t.Reset();for (int i=0; i<COUNTSIZE; i++){Sqrt2(Array, ARRAYCOUNT, 1000.0f);}dTime = t.End();cout<<"Not Use SSE: "<<dTime<<"毫秒"<<endl;//最小值cout<<"最小值:"<<endl;t.Reset();for (int i=0; i<COUNTSIZE; i++){Min1(Array, ARRAYCOUNT, 1000.0f);}dTime = t.End();cout<<"Use SSE: "<<dTime<<"毫秒"<<endl;t.Reset();for (int i=0; i<COUNTSIZE; i++){Min2(Array, ARRAYCOUNT, 1000.0f);}dTime = t.End();cout<<"Not Use SSE: "<<dTime<<"毫秒"<<endl;//最大值cout<<"最大值:"<<endl;t.Reset();for (int i=0; i<COUNTSIZE; i++){Max1(Array, ARRAYCOUNT, 1000.0f);}dTime = t.End();cout<<"Use SSE: "<<dTime<<"毫秒"<<endl;t.Reset();for (int i=0; i<COUNTSIZE; i++){Max2(Array, ARRAYCOUNT, 1000.0f);}dTime = t.End();cout<<"Not Use SSE: "<<dTime<<"毫秒"<<endl;//与操作cout<<"与操作:"<<endl;t.Reset();for (int i=0; i<COUNTSIZE; i++){And1(Array, ARRAYCOUNT, 1000.0f);}dTime = t.End();cout<<"Use SSE: "<<dTime<<"毫秒"<<endl;t.Reset();for (int i=0; i<COUNTSIZE; i++){And2(Array, ARRAYCOUNT, 1000.0f);}dTime = t.End();cout<<"Not Use SSE: "<<dTime<<"毫秒"<<endl;system("pause");return 0;}

SSE 加速运算例子详解:乘法、加法、平方、最小值、最大值、与操作相关推荐

  1. 论vue3.0和vue2.0区别之编程方式及例子详解

    系列文章目录 第一章 论vue3.0和vue2.0区别之编程方式及例子详解 第二章 同一台电脑 实现 vue-cli2和vue-cli3同时并存 及 常见命令 第三章 vue3.0项目实战 - Ele ...

  2. 浮点数的加减法运算过程详解(面向小白的)

    浮点数的加减法运算过程详解(面向小白的) 一. 浮点数在计算机内的表示 二. 浮点数的加减运算步骤 第一次写博客,难免有疏漏之处,如果有错误请批评指正,感谢! 对于浮点数的加减运算,书上写的名词太多, ...

  3. python布尔类型运算_Python对象类型及其运算方法(详解)

    基本要点: 程序中储存的所有数据都是对象(可变对象:值可以修改 不可变对象:值不可修改) 每个对象都有一个身份.一个类型.一个值 例: >>> a1 = 'abc' >> ...

  4. Python算法教程第一章知识点:利用插入元素的例子详解list之本质

    声明:由于中译本翻译过于冗余,所以将有用处的知识点罗列出来. 微信公众号:geekkr 本文目录:一.利用插入元素的例子详解list之本质 </br> 一.利用插入元素的例子详解list之 ...

  5. 运算符“||”与“|”,“”和“”的区别 (附带各类位运算符号详解(、|、^、~、<<、>>、>>>)

    区别一: 定义不同: || 和 | 都是表示"或",区别是||只要满足第一个条件,后面的条件就不再判断,而|要对所有的条件进行判断. 区别二: 与操作和或操作的区别 (1)在Jav ...

  6. 原创:Spark中GraphX图运算pregel详解

    原创:Spark中GraphX图运算pregel详解 由于本人文字表达能力不足,还是多多以代码形式表述,首先展示测试代码,然后解释: package com.txq.spark.test import ...

  7. latex画流程图例子详解,如何画转折线,运行不出来?

    先说如何画转折线? 思路:定义点,用点作为过渡.具体详见下面的例子 运行不出来? 可能是没有加分号; 比如:\node (stop) [startstop, below of=n3] {结束}; 例子 ...

  8. 站长在线Python精讲:Python中集合的交集、并集、差集和对称差集运算方法详解

    欢迎你来到站长在线的站长学堂学习Python知识,本文学习的是<Python中集合的交集.并集.差集和对称差集运算方法详解>.主要讲的是集合运算的相关的概念,及运算方法,包括:集合的交集. ...

  9. 【RDMA】技术详解(二):Send Receive操作

    原文:RDMA技术详解(二):RDMA Send Receive操作_Master-TJ的个人博客-CSDN博客 英文:Quick Concepts Part 1 – Introduction to ...

最新文章

  1. Java 数据持久化系列之池化技术
  2. 我的学习之路_第十八章_SQL语句
  3. 2012 Microsoft Intern Hiring Written Test [转]
  4. Application Performance Management Monitoring | New Relic
  5. centos 6.9 NTP基准时间服务器配置
  6. 3个Gmail 邀请,先进先出!!
  7. 找准多变量迭代过程的每一次变量转化(洛谷P1150题题解,Java语言描述)
  8. 木兰编程语言当事人被停职:自主创新何时当得起科技自立?
  9. C语言 传值和传指针的区别
  10. 使用jdbcTemplate查询返回自定义对象集合
  11. quartz 2.0持久化到mysql_SpringBoot2.0整合Quartz定时任务(持久化到数据库,更为简单的方式)...
  12. [JAVA][Eclipse]JVM terminated. Exit code=13
  13. jqueryUI日期控件和时间控件
  14. STM32F103系列(二):如何使用串口下载程序
  15. 内网外网双通下的一种网络拓补方案
  16. 《排序算法篇》快排的递归与非递归
  17. MySQL从入门到放弃(三)
  18. 现代处理器的设计思想
  19. halcon编程入门七——halco算子大全
  20. 【夯实Dubbo】Dubbo的核心特性

热门文章

  1. 【C/C++】左旋字符串
  2. DBeaver Enterprise21.0 企业版激活方法 DBeaver mac激活 DBeaver
  3. 知识付费APP开发基本功能解析
  4. 个股普跌沪指失守4000点
  5. 什么是IP路由?思科与华为在IP路由配置上有啥区别?
  6. 吃一堑长一智!带你快速通过字节跳动面试,知乎上转疯了!
  7. 东软实训项目个人总结
  8. 学习CSS Scroll Snapping与scroll-snap-align
  9. java异步回调历程
  10. TestNG的HelloWorld例子以及如何在命令行下运行