上面的Sandy Bridge扩展了指令集以支持8元素向量算法。 考虑这个实现。

struct MATRIX {

union {

float f[4][4];

__m128 m[4];

__m256 n[2];

};

};

MATRIX myMultiply(MATRIX M1, MATRIX M2) {

// Perform a 4x4 matrix multiply by a 4x4 matrix

// Be sure to run in 64 bit mode and set right flags

// Properties, C/C++, Enable Enhanced Instruction, /arch:AVX

// Having MATRIX on a 32 byte bundry does help performance

MATRIX mResult;

__m256 a0, a1, b0, b1;

__m256 c0, c1, c2, c3, c4, c5, c6, c7;

__m256 t0, t1, u0, u1;

t0 = M1.n[0]; // t0 = a00, a01, a02, a03, a10, a11, a12, a13

t1 = M1.n[1]; // t1 = a20, a21, a22, a23, a30, a31, a32, a33

u0 = M2.n[0]; // u0 = b00, b01, b02, b03, b10, b11, b12, b13

u1 = M2.n[1]; // u1 = b20, b21, b22, b23, b30, b31, b32, b33

a0 = _mm256_shuffle_ps(t0, t0, _MM_SHUFFLE(0, 0, 0, 0)); // a0 = a00, a00, a00, a00, a10, a10, a10, a10

a1 = _mm256_shuffle_ps(t1, t1, _MM_SHUFFLE(0, 0, 0, 0)); // a1 = a20, a20, a20, a20, a30, a30, a30, a30

b0 = _mm256_permute2f128_ps(u0, u0, 0x00); // b0 = b00, b01, b02, b03, b00, b01, b02, b03

c0 = _mm256_mul_ps(a0, b0); // c0 = a00*b00 a00*b01 a00*b02 a00*b03 a10*b00 a10*b01 a10*b02 a10*b03

c1 = _mm256_mul_ps(a1, b0); // c1 = a20*b00 a20*b01 a20*b02 a20*b03 a30*b00 a30*b01 a30*b02 a30*b03

a0 = _mm256_shuffle_ps(t0, t0, _MM_SHUFFLE(1, 1, 1, 1)); // a0 = a01, a01, a01, a01, a11, a11, a11, a11

a1 = _mm256_shuffle_ps(t1, t1, _MM_SHUFFLE(1, 1, 1, 1)); // a1 = a21, a21, a21, a21, a31, a31, a31, a31

b0 = _mm256_permute2f128_ps(u0, u0, 0x11); // b0 = b10, b11, b12, b13, b10, b11, b12, b13

c2 = _mm256_mul_ps(a0, b0); // c2 = a01*b10 a01*b11 a01*b12 a01*b13 a11*b10 a11*b11 a11*b12 a11*b13

c3 = _mm256_mul_ps(a1, b0); // c3 = a21*b10 a21*b11 a21*b12 a21*b13 a31*b10 a31*b11 a31*b12 a31*b13

a0 = _mm256_shuffle_ps(t0, t0, _MM_SHUFFLE(2, 2, 2, 2)); // a0 = a02, a02, a02, a02, a12, a12, a12, a12

a1 = _mm256_shuffle_ps(t1, t1, _MM_SHUFFLE(2, 2, 2, 2)); // a1 = a22, a22, a22, a22, a32, a32, a32, a32

b1 = _mm256_permute2f128_ps(u1, u1, 0x00); // b0 = b20, b21, b22, b23, b20, b21, b22, b23

c4 = _mm256_mul_ps(a0, b1); // c4 = a02*b20 a02*b21 a02*b22 a02*b23 a12*b20 a12*b21 a12*b22 a12*b23

c5 = _mm256_mul_ps(a1, b1); // c5 = a22*b20 a22*b21 a22*b22 a22*b23 a32*b20 a32*b21 a32*b22 a32*b23

a0 = _mm256_shuffle_ps(t0, t0, _MM_SHUFFLE(3, 3, 3, 3)); // a0 = a03, a03, a03, a03, a13, a13, a13, a13

a1 = _mm256_shuffle_ps(t1, t1, _MM_SHUFFLE(3, 3, 3, 3)); // a1 = a23, a23, a23, a23, a33, a33, a33, a33

b1 = _mm256_permute2f128_ps(u1, u1, 0x11); // b0 = b30, b31, b32, b33, b30, b31, b32, b33

c6 = _mm256_mul_ps(a0, b1); // c6 = a03*b30 a03*b31 a03*b32 a03*b33 a13*b30 a13*b31 a13*b32 a13*b33

c7 = _mm256_mul_ps(a1, b1); // c7 = a23*b30 a23*b31 a23*b32 a23*b33 a33*b30 a33*b31 a33*b32 a33*b33

c0 = _mm256_add_ps(c0, c2); // c0 = c0 + c2 (two terms, first two rows)

c4 = _mm256_add_ps(c4, c6); // c4 = c4 + c6 (the other two terms, first two rows)

c1 = _mm256_add_ps(c1, c3); // c1 = c1 + c3 (two terms, second two rows)

c5 = _mm256_add_ps(c5, c7); // c5 = c5 + c7 (the other two terms, second two rose)

// Finally complete addition of all four terms and return the results

mResult.n[0] = _mm256_add_ps(c0, c4); // n0 = a00*b00+a01*b10+a02*b20+a03*b30 a00*b01+a01*b11+a02*b21+a03*b31 a00*b02+a01*b12+a02*b22+a03*b32 a00*b03+a01*b13+a02*b23+a03*b33

// a10*b00+a11*b10+a12*b20+a13*b30 a10*b01+a11*b11+a12*b21+a13*b31 a10*b02+a11*b12+a12*b22+a13*b32 a10*b03+a11*b13+a12*b23+a13*b33

mResult.n[1] = _mm256_add_ps(c1, c5); // n1 = a20*b00+a21*b10+a22*b20+a23*b30 a20*b01+a21*b11+a22*b21+a23*b31 a20*b02+a21*b12+a22*b22+a23*b32 a20*b03+a21*b13+a22*b23+a23*b33

// a30*b00+a31*b10+a32*b20+a33*b30 a30*b01+a31*b11+a32*b21+a33*b31 a30*b02+a31*b12+a32*b22+a33*b32 a30*b03+a31*b13+a32*b23+a33*b33

return mResult;

}

c语言 4x4矩阵乘法,c - 高效的4x4矩阵乘法(C vs汇编) - 堆栈内存溢出相关推荐

  1. java中图片与像素矩阵转换,java - Java中具有矩阵乘法的图片转换不起作用 - 堆栈内存溢出...

    我正在用Java实现图片转换. 到目前为止,我已经实现了以下类: 矩阵 (持有一个3x3矩阵,该矩阵将用于与Vector相乘) 向量 (用于与变换矩阵相乘以生成原始图像像素的新位置) PictureT ...

  2. 计算机中乘法是什么函数,c - 分解简单的C函数。 (在64位计算机中为128位乘法) - 堆栈内存溢出...

    我正在一本名为"计算机系统"的书中解决问题. 这是我正在努力解决的问题. 问题:以下代码计算两个64位带符号值x和y的128位乘积并将结果存储在内存中: 1 typedef __i ...

  3. c语言 case语句用大括号,c++ - 关于“ switch”中“ case”语句中的花括号 - 堆栈内存溢出...

    今天,当我尝试编写代码以仅对两个2 * 2矩阵进行加法和减法时,我使用了switch语句,但出现了一个错误: 函数main()中局部变量的大小写绕过初始化 代码 #include #include # ...

  4. c语言gcno文件位置,makefile - 具有覆盖率的CMake Ninja将gcno文件放在根二进制目录中 - 堆栈内存溢出...

    我正在使用忍者生成器通过cmake构建一个项目,并使用add_compile_options("$:-g;-O0;-ftest-coverage;-fprofile-arcs;-fno-bu ...

  5. c语言 删除小写字母,c++ - 使用C字符串和指针。 删除除小写字母和空格以外的所有字符 - 堆栈内存溢出...

    当您决定从字符串中删除一个字符时,您可以将剩余的字符向左移动一个位置,这很好,但是无论该字符的实际值如何,都可以在该字符开始移动后的位置跳过该字符是. 这就是为什么您在输出中看到不需要的字符的原因. ...

  6. c语言sort函数排序二维数组,c++ - 如何使用stl sort函数根据第二列对二维数组进行排序? - 堆栈内存溢出...

    stl排序要求迭代器的rvalue作为参数传递. 如果你想使用sort函数,你必须在c ++ 11中编译并使用数组stl来存储数组. 代码如下 #include "bits/stdc++.h ...

  7. c语言printf %llo,c++ - Printf疯狂了 - 堆栈内存溢出

    你不能使用%d来打印long long . 你必须使用%lld . (因此请使用"\\n%d %d | %lld %lld | %d %d"作为格式字符串.) 特别是,显而易见的是 ...

  8. c语言编程无法生成dat文件格式,c++ - 无法从.dat文件读取数据(从Simulink创建的VS2012 C ++项目) - 堆栈内存溢出...

    编辑:谢谢,对那些感兴趣的人的固定代码:ert_main.cpp: #include /* This ert_main.c example uses printf/fflush */ #include ...

  9. c语言kbhit函数头文件,c - 有没有办法替换标准C中的kbhit()和getch()函数? - 堆栈内存溢出...

    我试图获得与控制台交互的快速时间事件类型,并设法使用conio库获得了它. 不幸的是,我正在从事的项目要求代码必须在Windows和Linux上都可以编译,但我想不出一种改变它的方法. 我可以做些什么 ...

最新文章

  1. kubeadm源码分析(内含kubernetes离线包,三步安装)
  2. Linux下的find命令
  3. 通过Clocking Wizard定制和生成一个IP核(MMCM)(Virtex7)(ISE版)
  4. clipboard_monitor_in_win7
  5. python 代码转程序_python将代码转换成网页
  6. WTL 自绘 进度条Progressbar
  7. python怎么定义正方形函数_python – Matplotlib自定义图例以显示正方形而不是矩形...
  8. HTMLTestRunner.py内容
  9. Intel 64/x86_64/x86/IA-32处理器标志寄存器详解(3) - 32位EFLAGS - 概述
  10. _系列 | 全自动泊车辅助F-APA简介(系列一)
  11. undefined reference to `crypto_get_random'
  12. java在线订单系统源码_春哥酒店在线预订微信小程序源码系统正式发布!
  13. 主流浏览器兼容性问题与解决方案
  14. 两台电脑间的串口通信
  15. html5中translate,css3 中translate和transition的使用方法
  16. 麻省理工学院公开课:单变量微积分
  17. Android UI基础控件
  18. 计算机硬盘写入错误怎么办,永劫无间磁盘写入错误怎么办 磁盘写入错误解决办法...
  19. 一周肝出Linux之远程服务详解(ssh远程登录、scp远程复制、sftp安全下载、TCP Wrappers访问控制)
  20. 修改ntoskrnl.exe的方法

热门文章

  1. [CF626E]Simple Skewness
  2. python中opener_Python request.build_opener方法代码示例
  3. OFDM载波间隔_如果用30Khz子载波间隔会比15Khz子载波间隔传递的有效数据少吗?...
  4. 在Uni-App中使用阿里字体图标库
  5. python爬取中关村手机信息
  6. 微信公众号测试账号申请,后台获取公众号关注取关事件,获取用户发送消息
  7. 关于iou,GIOU, iou-net
  8. RMII/GMII/MII
  9. 2017年春节期间阅读清单
  10. 转录组分析流程:比对(有参)及统计Counts矩阵