sse矩阵乘法 应该是1毫秒纯运算1000次
#include <intrin.h>
#include <math.h> struct Vector4
{
float x, y, z, w;
}; struct Matrix
{
float _M[][]; public: //单位化
void Identity()
{
ZeroMemory((void*)_M,sizeof(float)*);
_M[][] = 1.0f;
_M[][] = 1.0f;
_M[][] = 1.0f;
_M[][] = 1.0f;
} //转置矩阵
Matrix Transpose()
{
Matrix ret;
ret._M[][] = _M[][];
ret._M[][] = _M[][];
ret._M[][] = _M[][];
ret._M[][] = _M[][]; ret._M[][] = _M[][];
ret._M[][] = _M[][];
ret._M[][] = _M[][];
ret._M[][] = _M[][]; ret._M[][] = _M[][];
ret._M[][] = _M[][];
ret._M[][] = _M[][];
ret._M[][] = _M[][]; ret._M[][] = _M[][];
ret._M[][] = _M[][];
ret._M[][] = _M[][];
ret._M[][] = _M[][];
return ret;
}
}; float Sum(const Vector4 & arg1)
{ return arg1.x + arg1.y + arg1.z + arg1.w; } Vector4 Normaliz(Vector4 v1)
{
Vector4 v2;
float k = /sqrtf(v1.x * v1.x + v1.y * v1.y + v1.z * v1.z);
v2.x = v1.x * k;
v2.y = v1.y * k;
v2.z = v1.z * k;
return v2;
} //向量相加
Vector4 SSE_VectiorAdd ( const Vector4 &Op_A, const Vector4 &Op_B )
{
Vector4 Ret_Vector; __asm
{
MOV EAX, Op_A // Load pointers into CPU regs
MOV EBX, Op_B MOVUPS XMM0, [EAX] // Move unaligned vectors to SSE regs
MOVUPS XMM1, [EBX] ADDPS XMM0, XMM1 // v1 + v2
MOVUPS [Ret_Vector], XMM0 // Save the return vector
} return Ret_Vector;
} //向量叉乘
Vector4 SSE_VectorCross(const Vector4 &Op_A, const Vector4 &Op_B)
{
Vector4 Ret_Vector;
__asm
{
MOV EAX, Op_A // Load pointers into CPU regs
MOV EBX, Op_B MOVUPS XMM0, [EAX] // Move unaligned vectors to SSE regs
MOVUPS XMM1, [EBX]
MOVAPS XMM2, XMM0 // Make a copy of vector A
MOVAPS XMM3, XMM1 // Make a copy of vector B SHUFPS XMM0, XMM0, 0xD8 // 11 01 10 00 Flip the middle elements of A
SHUFPS XMM1, XMM1, 0xE1 // 11 10 00 01 Flip first two elements of B
MULPS XMM0, XMM1 // Multiply the modified register vectors SHUFPS XMM2, XMM2, 0xE1 // 11 10 00 01 Flip first two elements of the A copy
SHUFPS XMM3, XMM3, 0xD8 // 11 01 10 00 Flip the middle elements of the B copy
MULPS XMM2, XMM3 // Multiply the modified register vectors SUBPS XMM0, XMM2 // Subtract the two resulting register vectors MOVUPS [Ret_Vector], XMM0 // Save the return vector
}
return Ret_Vector;
} //向量缩放
Vector4 SSE_VectorScale(const Vector4 &Op_A, const float &Op_B)
{
Vector4 Ret_Vector; __m128 F = _mm_set1_ps(Op_B); // Create a 128 bit vector with four elements Op_B __asm
{
MOV EAX, Op_A // Load pointer into CPU reg
MOVUPS XMM0, [EAX] // Move the vector to an SSE reg
MULPS XMM0, F // Multiply vectors
MOVUPS [Ret_Vector], XMM0 // Save the return vector
}
return Ret_Vector;
} void SSE_VectorDot(const Vector4 &Op_A, const Vector4 &Op_B,float& ret)
{
Vector4 v1; //__m128 F = _mm_set1_ps(Op_B); // Create a 128 bit vector with four elements Op_B __asm
{
MOV EAX, Op_A // Load pointer into CPU reg
MOV EBX, Op_B
MOVUPS XMM1, [EBX]
MOVUPS XMM0, [EAX] // Move the vector to an SSE reg
MULPS XMM0,XMM1 // Multiply vectors
MOVUPS [v1], XMM0 // Save the return vector
} ret = v1.x + v1.y + v1.z; } void SSE_VectorMultiplyMatrix(const Vector4& v,const Matrix& m1,Vector4& ret)
{
Vector4 va,vb,vc,vd;
Vector4 *pva,*pvb,*pvc,*pvd;
const Vector4 *pv; //取出矩阵每一列
va.x = m1._M[][];
va.y = m1._M[][];
va.z = m1._M[][];
va.w = m1._M[][]; vb.x = m1._M[][];
vb.y = m1._M[][];
vb.z = m1._M[][];
vb.w = m1._M[][]; vc.x = m1._M[][];
vc.y = m1._M[][];
vc.z = m1._M[][];
vc.w = m1._M[][]; vd.x = m1._M[][];
vd.y = m1._M[][];
vd.z = m1._M[][];
vd.w = m1._M[][]; pva = &va;
pvb = &vb;
pvc = &vc;
pvd = &vd;
pv = &v;
__asm
{
//矩阵四列放入mmx0-mmx3
MOV EAX, pva // Load pointer into CPU reg
MOVUPS XMM0, [EAX]
MOV EAX, pvb // Load pointer into CPU reg
MOVUPS XMM1, [EAX]
MOV EAX, pvc // Load pointer into CPU reg
MOVUPS XMM2, [EAX]
MOV EAX, pvd // Load pointer into CPU reg
MOVUPS XMM3, [EAX] //向量放入 mmx4
MOV EAX, pv
MOVUPS XMM4, [EAX] //向量点乘矩阵每列
MULPS XMM0,XMM4
MULPS XMM1,XMM4
MULPS XMM2,XMM4
MULPS XMM3,XMM4 //输出四个分量
MOVUPS [va], XMM0
MOVUPS [vb], XMM1
MOVUPS [vc], XMM2
MOVUPS [vd], XMM3
} //四个分量求和得变换后向量
ret.x = va.w + va.x + va.y + va.z;
ret.y = vb.w + vb.x + vb.y + vb.z;
ret.z = vc.w + vc.x + vc.y + vc.z;
ret.w = vd.w + vd.x + vd.y + vd.z; } void SSE_MatrixMultiplyMatrix(const Matrix& arg1,const Matrix& arg2,Matrix & ret)
{
Matrix m1,m2;
Vector4 v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,v11,v12,v13,v14,v15,v16;
Vector4 *pv1,*pv2,*pv3,*pv4,*pv5,*pv6,*pv7,*pv8;
m1 = arg1;
m2 = arg2;
m2 = m2.Transpose(); pv1 = (Vector4*)&m1._M[][];
pv2 = (Vector4*)&m1._M[][];
pv3 = (Vector4*)&m1._M[][];
pv4 = (Vector4*)&m1._M[][]; pv5 = (Vector4*)&m2._M[][];
pv6 = (Vector4*)&m2._M[][];
pv7 = (Vector4*)&m2._M[][];
pv8 = (Vector4*)&m2._M[][]; __asm
{
MOV EAX, pv5
MOV EBX, pv6
MOV ECX, pv7
MOV EDX, pv8
MOVUPS XMM1, [EAX]
MOVUPS XMM2, [EBX]
MOVUPS XMM3, [ECX]
MOVUPS XMM4, [EDX]
MOV EAX, pv1
MOVUPS XMM0, [EAX] MULPS XMM1, XMM0
MOVUPS[v1], XMM1
MULPS XMM2, XMM0
MOVUPS[v2], XMM2
MULPS XMM3, XMM0
MOVUPS[v3], XMM3
MULPS XMM4, XMM0
MOVUPS[v4], XMM4 MOV EAX, pv5
MOV EBX, pv6
MOV ECX, pv7
MOV EDX, pv8
MOVUPS XMM1, [EAX]
MOVUPS XMM2, [EBX]
MOVUPS XMM3, [ECX]
MOVUPS XMM4, [EDX]
MOV EAX, pv2
MOVUPS XMM0, [EAX]
MULPS XMM1, XMM0
MOVUPS[v5], XMM1
MULPS XMM2, XMM0
MOVUPS[v6], XMM2
MULPS XMM3, XMM0
MOVUPS[v7], XMM3
MULPS XMM4, XMM0
MOVUPS[v8], XMM4 MOV EAX, pv5
MOV EBX, pv6
MOV ECX, pv7
MOV EDX, pv8
MOVUPS XMM1, [EAX]
MOVUPS XMM2, [EBX]
MOVUPS XMM3, [ECX]
MOVUPS XMM4, [EDX]
MOV EAX, pv3
MOVUPS XMM0, [EAX]
MULPS XMM1, XMM0
MOVUPS[v9], XMM1
MULPS XMM2, XMM0
MOVUPS[v10], XMM2
MULPS XMM3, XMM0
MOVUPS[v11], XMM3
MULPS XMM4, XMM0
MOVUPS[v12], XMM4 MOV EAX, pv5
MOV EBX, pv6
MOV ECX, pv7
MOV EDX, pv8
MOVUPS XMM1, [EAX]
MOVUPS XMM2, [EBX]
MOVUPS XMM3, [ECX]
MOVUPS XMM4, [EDX]
MOV EAX, pv4
MOVUPS XMM0, [EAX]
MULPS XMM1, XMM0
MOVUPS[v13], XMM1
MULPS XMM2, XMM0
MOVUPS[v14], XMM2
MULPS XMM3, XMM0
MOVUPS[v15], XMM3
MULPS XMM4, XMM0
MOVUPS[v16], XMM4
} ret._M[][] = Sum(v1);
ret._M[][] = Sum(v2);
ret._M[][] = Sum(v3);
ret._M[][] = Sum(v4); ret._M[][] = Sum(v5);
ret._M[][] = Sum(v6);
ret._M[][] = Sum(v7);
ret._M[][] = Sum(v8); ret._M[][] = Sum(v9);
ret._M[][] = Sum(v10);
ret._M[][] = Sum(v11);
ret._M[][] = Sum(v12); ret._M[][] = Sum(v13);
ret._M[][] = Sum(v14);
ret._M[][] = Sum(v15);
ret._M[][] = Sum(v16); return;
}
#include <Windows.h>
#include <iostream>
#include <math.h>
#include "sse.h" using namespace std; void main(int argc, char **argv)
{ Matrix m1,m2,mRet;
m1.Identity();
m2.Identity();
float time;
time = GetTickCount(); for (int t = ; t < ; t++)
{
SSE_MatrixMultiplyMatrix(m1,m2,mRet);
} time = GetTickCount() - time;
_asm {
int
}
return;
}
sse矩阵乘法 应该是1毫秒纯运算1000次的更多相关文章
- hdu 5068(线段树+矩阵乘法)
矩阵乘法来进行所有路径的运算, 线段树来查询修改. 关键还是矩阵乘法的结合律. Harry And Math Teacher Time Limit: 5000/3000 MS (Java/Others ...
- Codeforces 576D - Flights for Regular Customers(bitset 优化广义矩阵乘法)
题面传送门 题意: 有一张 \(n\) 个点 \(m\) 条边的有向图,你初始在 \(1\) 号点,边上有边权 \(c_i\) 表示只有当你经过至少 \(c_i\) 条边的时候你才能经过第 \(i\) ...
- [转]OpenBLAS项目与矩阵乘法优化
课程内容 OpenBLAS项目介绍 矩阵乘法优化算法 一步步调优实现 以下为公开课完整视频,共64分钟: 以下为公开课内容的文字及 PPT 整理. 雷锋网的朋友们大家好,我是张先轶,今天主要介绍一下我 ...
- OpenGL学习进程(12)第九课:矩阵乘法实现3D变换
本节是OpenGL学习的第九个课时,下面将详细介绍OpenGL的多种3D变换和如何操作矩阵堆栈. (1)3D变换: OpenGL中绘制3D世界的空间变换包括:模型变换.视图变换.投影变换和视口 ...
- 【模拟题(电子科大MaxKU)】解题报告【树形问题】【矩阵乘法】【快速幂】【数论】
目录: 1:一道简单题[树形问题](Bzoj 1827 奶牛大集会) 2:一道更简单题[矩阵乘法][快速幂] 3:最简单题[技巧] 话说这些题目的名字也是够了.... 题目: 1.一道简单题 时间1s ...
- OpenCL 矩阵乘法
▶ 矩阵乘法,按照书里的内容进行了几方面的优化,包括局部内存,矢量数据类型,寄存器,流水线等. ● 最直接的乘法.调用时 main.c 中使用 size_t globalSize[] = { rowA ...
- *HDU2254 矩阵乘法
奥运 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submissi ...
- *HDU 1757 矩阵乘法
A Simple Math Problem Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...
- CH Round #30 摆花[矩阵乘法]
摆花 CH Round #30 - 清明欢乐赛 背景及描述 艺术馆门前将摆出许多花,一共有n个位置排成一排,每个位置可以摆花也可以不摆花.有些花如果摆在相邻的位置(隔着一个空的位置不算相邻),就不好看 ...
随机推荐
- Dva三种方式实现dispatch的Promise回调
Dva2.0及以上版本 使用官方自带的Promise // 业务组件 e.g: Tags.js dispatch({ type: 'user/add', payload: {}, // 需要传递的信息 ...
- 在 Laravel 项目中使用 Elasticsearch 做引擎,scout 全文搜索(小白出品, 绝对白话)
项目中需要搜索, 所以从零开始学习大家都在用的搜索神器 elasiticsearch. 刚开始 google 的时候, 搜到好多经验贴和视频(中文的, 英文的), 但是由于是第一次接触, 一点概念都没 ...
- react初探(一)之JSX、状态(state)管理、条件渲染、事件处理
前言: 最近收到组长通知我们项目组后面新开的项目准备统一技术栈为react,目前我的情况是三大框架只会angular和Vue.在实际项目中只使用过一次angular5,其余项目都是使用Vue写的.写篇 ...
- 【安卓进阶】Scroller理解与应用
项目中有个需求,就是在RecyclerView的item中进行侧滑,一开始同事推荐了一个开源库,使用起来确实也方便好用,直接在布局作为父布局即可实现侧滑. 自己也非常好奇这个开源库到底用了什么API能 ...
- [Database]Oracle数据库中concat和||的区别
注:在oracle中,需要上述多次拼接应使用||,因为concat()一次只能拼接2个,需要多次嵌套.而在mysql中,可以实现concat(col1,col2,coln....) 官方文档链接:CO ...
- 金蝶K3常用数据表
金蝶K3WISE常用数据表 K3Wise 14.2 清空密码update t_User set FSID=') F ", ,P T #8 *P!D &D 80!N &@ &l ...
- 序列比对和构建进化树(clustalw和phylip)
安装clustalw很简单,不提了. 找了几个蛋白序列进行比对,命名为dm.fasta 1.输入 ./clustalw2 进入交互模式 2.选择1 并输入文件名字 3.输入2, 进行多序列比对 4. ...
- 【原】HDMI输出接口传输速率计算
1.1080P60为例: 三组差分线 R.G.B,每组速率: R:1920x1080(像素)x10(有效位为8bit,按10bit传输)x60(帧率)= 1244160000 ~~1.25G bit/ ...
- 8.5 GOF设计模式四: 观察者模式Observer
GOF设计模式四: 观察者模式Observer 现实中遇到的问题 当有许多不同的客户都对同一数据源感兴趣,对相同的数据有不同的处理方式,该如 何解决?5.1 定义: 观察者模式 观察者模式 ...
- QVector常见使用方法
仅在此简单介绍QVector的一些常见函数,有兴趣的可以查下QT,在QT中介绍的很详细 构造函数,QVector的构造函数很多样化,常见的有 QVector() 无参的构造函数 QVector(int ...