1. SSE的整型指令

// 测试SSE的整型指令
void TestSSEInteger()
{    __m64 a;
    a.m64_i16[0] = 654;
    a.m64_i16[1] = -25;
    a.m64_i16[2] = 35;
    a.m64_i16[3] = 45; __m64 b;
    b.m64_i16[0] = 456;
    b.m64_i16[1] = 28;
    b.m64_i16[2] = -5;
    b.m64_i16[3] = 50; // a的4个数中插入一个立即数,第三个参数指定插入的位置
    __m64 c = _mm_insert_pi16(a, 90, 1);
    printf("a: (%d, %d, %d, %d)\n\n", a.m64_i16[0], a.m64_i16[1], a.m64_i16[2], a.m64_i16[3]);
    printf("b: (%d, %d, %d, %d)\n\n", b.m64_i16[0], b.m64_i16[1], b.m64_i16[2], b.m64_i16[3]);
    printf("c: (%d, %d, %d, %d)\n\n", c.m64_i16[0], c.m64_i16[1], c.m64_i16[2], c.m64_i16[3]);    // 从a中取出一个16位无符号数
    int a0 = _mm_extract_pi16(a, 0);
    int a1 = _mm_extract_pi16(a, 1);
    int a2 = _mm_extract_pi16(a, 2);
    int a3 = _mm_extract_pi16(a, 3);
    printf("(a0, a1, a2, a3) : (%d, %d, %d, %d)\n\n", a0, a1, a2, a3);    // 得出a、b中对应位置的最大值和最小值
    __m64 iMax = _mm_max_pi16(a, b);
    __m64 iMin = _mm_min_pi16(a, b);
    printf("iMax: (%d, %d, %d, %d)\n\n", iMax.m64_i16[0], iMax.m64_i16[1], iMax.m64_i16[2], iMax.m64_i16[3]);
    printf("iMin: (%d, %d, %d, %d)\n\n", iMin.m64_i16[0], iMin.m64_i16[1], iMin.m64_i16[2], iMin.m64_i16[3]); // 从n的最重要的比特位中创造出1个8位的掩码
    __m64 n;
    n.m64_i8[0] = 7;       // sign(n0) = 0        // n.m64_u8[0] = 7;
    n.m64_i8[1] = -12;     // sign(n1) = 1;   // n.m64_u8[1] = 244;
    n.m64_i8[2] = 23;      // sign(n2) = 0;   // n.m64_u8[2] = 23;
    n.m64_i8[3] = -32;     // sign(n3) = 1;   // n.m64_u8[3] = 224;
    n.m64_i8[4] = -5;      // sign(n4) = 1;   // n.m64_u8[4] = 251;
    n.m64_i8[5] = 2;       // sign(n5) = 0;   // n.m64_u8[5] = 2;
    n.m64_i8[6] = 62;      // sign(n6) = 0;   // n.m64_u8[6] = 62;
    n.m64_i8[7] = -44;     // sign(n7) = 1;   // n.m64_u8[7] = 212;
    int mask = _mm_movemask_pi8(n);
    printf("mask: 0x%x\n\n", mask);       // mask = 0x9A // a和b的无符号相乘,返回32位中间结果的高16位
    __m64 ab = _mm_mulhi_pu16(a, b);
    printf("ab: (%d, %d, %d, %d)\n\n", ab.m64_i16[0], ab.m64_i16[1], ab.m64_i16[2], ab.m64_i16[3]);   // 根据第二个参数返回a的4个数的一个联合
    __m64 e1 = _mm_shuffle_pi16(a, 0x23);      // a[3], a[0], a[2], a[0]
    __m64 e2 = _mm_shuffle_pi16(a, 0x32);      // a[2], a[0], a[3], a[0]
    __m64 e3 = _mm_shuffle_pi16(a, 0x51);      // a[1], a[0], a[1], a[1]
    __m64 e4 = _mm_shuffle_pi16(a, 0x76);      // a[2], a[1], a[3], a[1]
    printf("e1: (%d, %d, %d, %d)\n\n", e1.m64_i16[0], e1.m64_i16[1], e1.m64_i16[2], e1.m64_i16[3]);
    printf("e2: (%d, %d, %d, %d)\n\n", e2.m64_i16[0], e2.m64_i16[1], e2.m64_i16[2], e2.m64_i16[3]);
    printf("e3: (%d, %d, %d, %d)\n\n", e3.m64_i16[0], e3.m64_i16[1], e3.m64_i16[2], e3.m64_i16[3]);
    printf("e4: (%d, %d, %d, %d)\n\n", e4.m64_i16[0], e4.m64_i16[1], e4.m64_i16[2], e4.m64_i16[3]);   // 有条件的向地址p中存储d的元素
    char p[8] = { 0 };
    __m64 d;
    d.m64_i8[0] = 11;      // d.m64_u8[0] = 11;
    d.m64_i8[1] = -22;     // d.m64_u8[1] = 234;
    d.m64_i8[2] = 33;      // d.m64_u8[2] = 33;
    d.m64_i8[3] = -44;     // d.m64_u8[3] = 212;
    d.m64_i8[4] = 55;      // d.m64_u8[4] = 55;
    d.m64_i8[5] = -66;     // d.m64_u8[5] = 190;
    d.m64_i8[6] = 77;      // d.m64_u8[6] = 77;
    d.m64_i8[7] = -88;     // d.m64_u8[7] = 168;
    _mm_maskmove_si64(d, n, p);
    printf("d: (%d, %d, %d, %d, %d, %d, %d, %d)\n\n", d.m64_i8[0], d.m64_i8[1], d.m64_i8[2], d.m64_i8[3],
                                                          d.m64_i8[4], d.m64_i8[5], d.m64_i8[6], d.m64_i8[7]);
    printf("n: (%d, %d, %d, %d, %d, %d, %d, %d)\n\n", n.m64_i8[0], n.m64_i8[1], n.m64_i8[2], n.m64_i8[3],
                                                          n.m64_i8[4], n.m64_i8[5], n.m64_i8[6], n.m64_i8[7]);
    printf("p: (%d, %d, %d, %d, %d, %d, %d, %d)\n\n", p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);

        // 得出n和d中的对应的8位无符号的最大值和最小值
    __m64 uMax = _mm_max_pu8(n, d);
    __m64 uMin = _mm_min_pu8(n, d);
    printf("uMax: (%u, %u, %u, %u, %u, %u, %u, %u)\n\n", uMax.m64_u8[0], uMax.m64_u8[1], uMax.m64_u8[2], uMax.m64_u8[3],
                                                             uMax.m64_u8[4], uMax.m64_u8[5], uMax.m64_u8[6], uMax.m64_u8[7]);
    printf("uMin: (%u, %u, %u, %u, %u, %u, %u, %u)\n\n", uMin.m64_u8[0], uMin.m64_u8[1], uMin.m64_u8[2], uMin.m64_u8[3],
                                                             uMin.m64_u8[4], uMin.m64_u8[5], uMin.m64_u8[6], uMin.m64_u8[7]);   // 计算a和b中16位无符号的平均值(round模式)
    // 计算n和d中8 位无符号的平均值(round模式)
    __m64 avg1 = _mm_avg_pu16(a, b);
    __m64 avg2 = _mm_avg_pu8(n, d);
    printf("avg1: (%d, %d, %d, %d)\n\n", avg1.m64_u16[0], avg1.m64_u16[1], avg1.m64_u16[2], avg1.m64_u16[3]);
    printf("avg2: (%d, %d, %d, %d, %d, %d, %d, %d)\n\n", avg2.m64_u8[0], avg2.m64_u8[1], avg2.m64_u8[2],
            avg2.m64_u8[3], avg2.m64_u8[4], avg2.m64_u8[4], avg2.m64_u8[6], avg2.m64_u8[7]);    // 计算n和d中无符号数的差的绝对值的总和,且高位置0
    __m64 sad = _mm_sad_pu8(n, d);
    printf("sad: (%d, %d, %d, %d)\n\n", sad.m64_u16[0], sad.m64_u16[1], sad.m64_u16[2], sad.m64_u16[3]);
}

测试结果:

  
2.  SSE的读写寄存器指令
// 测试SSE的读写寄存器指令
void TestSSECtlReg()
{    _mm_setcsr(0x9A);   // 0x9A = 154
    int value = _mm_getcsr();
    printf("value: %d\n", value);
}

测试结果:

   
3. SSE的混杂指令
// 测试SSE的混杂指令
void TestSSEMix()
{    __m128 a;
    a.m128_f32[0] = 10.15;         // sign(a0) = 0;
    a.m128_f32[1] = -20.25;            // sign(a1) = 1;
    a.m128_f32[2] = 30.35;         // sign(a2) = 0;
    a.m128_f32[3] = -40.45;            // sign(a3) = 1;   __m128 b;
    b.m128_f32[0] = 90.95;         // sign(b0) = 0;
    b.m128_f32[1] = 80.85;         // sign(b1) = 0;
    b.m128_f32[2] = -70.75;            // sign(b2) = 1;
    b.m128_f32[3] = 60.65;         // sign(b3) = 0;   printf("a: (%.2f, %.2f, %.2f, %.2f)\n\n", a.m128_f32[0], a.m128_f32[1], a.m128_f32[2], a.m128_f32[3]);
    printf("b: (%.2f, %.2f, %.2f, %.2f)\n\n", b.m128_f32[0], b.m128_f32[1], b.m128_f32[2], b.m128_f32[3]);    // 基于第三个参数(必须是立即数)从a和b中选择4个指定的单精度浮点数
    __m128 v1 = _mm_shuffle_ps(a, b, 0x76);            // a[2], a[1], b[3], b[1]
    __m128 v2 = _mm_shuffle_ps(a, b, 0x85);            // a[1], a[1], b[0], b[2]
    __m128 v3 = _mm_shuffle_ps(a, b, 0xB9);            // a[1], a[2], b[3], b[2]
    __m128 v4 = _mm_shuffle_ps(a, b, 0x1C);            // a[0], a[3], b[1], b[0]
    printf("v1: (%.2f, %.2f, %.2f, %.2f)\n\n", v1.m128_f32[0], v1.m128_f32[1], v1.m128_f32[2], v1.m128_f32[3]);
    printf("v2: (%.2f, %.2f, %.2f, %.2f)\n\n", v2.m128_f32[0], v2.m128_f32[1], v2.m128_f32[2], v2.m128_f32[3]);
    printf("v3: (%.2f, %.2f, %.2f, %.2f)\n\n", v3.m128_f32[0], v3.m128_f32[1], v3.m128_f32[2], v3.m128_f32[3]);
    printf("v4: (%.2f, %.2f, %.2f, %.2f)\n\n", v4.m128_f32[0], v4.m128_f32[1], v4.m128_f32[2], v4.m128_f32[3]);   // a和b中的高位2个或者低位2个SPFP进行交织
    __m128 v5 = _mm_unpackhi_ps(a, b);         // a[2], b[2], a[3], b[3]
    __m128 v6 = _mm_unpacklo_ps(a, b);         // a[0], b[0], a[1], b[1]
    printf("v5: (%.2f, %.2f, %.2f, %.2f)\n\n", v5.m128_f32[0], v5.m128_f32[1], v5.m128_f32[2], v5.m128_f32[3]);
    printf("v6: (%.2f, %.2f, %.2f, %.2f)\n\n", v6.m128_f32[0], v6.m128_f32[1], v6.m128_f32[2], v6.m128_f32[3]);   // 将a的低位置成b的、b的高位移动到a的低位、b的低位移动到a的高位
    __m128 v7 = _mm_move_ss(a, b);             // b[0], a[1], a[2], a[3]
    __m128 v8 = _mm_movehl_ps(a, b);           // b[2], b[3], a[2], a[3]
    __m128 v9 = _mm_movelh_ps(a, b);           // a[0], a[1], b[0], b[1]
    printf("v7: (%.2f, %.2f, %.2f, %.2f)\n\n", v7.m128_f32[0], v7.m128_f32[1], v7.m128_f32[2], v7.m128_f32[3]);
    printf("v8: (%.2f, %.2f, %.2f, %.2f)\n\n", v8.m128_f32[0], v8.m128_f32[1], v8.m128_f32[2], v8.m128_f32[3]);
    printf("v9: (%.2f, %.2f, %.2f, %.2f)\n\n", v9.m128_f32[0], v9.m128_f32[1], v9.m128_f32[2], v9.m128_f32[3]);   // 从4个SPFP的最重要比特位中创造1个4比特的掩码
    int maskA = _mm_movemask_ps(a);                // sign(a) : 1, 0, 1, 0 (从高到低), maskA = 10
    int maskB = _mm_movemask_ps(b);                // sign(b) : 0, 1, 0, 0 (从高到低), maskB = 4
    printf("maskA: %d\t maskB: %d\n", maskA, maskB);
}

测试结果:

  
4. SSE的矩阵变换宏函数
// 测试矩阵变换的宏函数
void TestSSEMatrixTrans()
{    __m128 row0;
    row0.m128_f32[0] = 1.0;
    row0.m128_f32[1] = 2.0;
    row0.m128_f32[2] = 3.0;
    row0.m128_f32[3] = 4.0;    __m128 row1;
    row1.m128_f32[0] = 5.0;
    row1.m128_f32[1] = 6.0;
    row1.m128_f32[2] = 7.0;
    row1.m128_f32[3] = 8.0;    __m128 row2;
    row2.m128_f32[0] = 9.0;
    row2.m128_f32[1] = 10.0;
    row2.m128_f32[2] = 11.0;
    row2.m128_f32[3] = 12.0;   __m128 row3;
    row3.m128_f32[0] = 13.0;
    row3.m128_f32[1] = 14.0;
    row3.m128_f32[2] = 15.0;
    row3.m128_f32[3] = 16.0;

    printf("row0:\t %.2f,  %.2f,  %.2f,  %.2f\n\n", row0.m128_f32[0], row0.m128_f32[1], row0.m128_f32[2], row0.m128_f32[3]);
    printf("row1:\t %.2f,  %.2f,  %.2f,  %.2f\n\n", row1.m128_f32[0], row1.m128_f32[1], row1.m128_f32[2], row1.m128_f32[3]);
    printf("row2:\t %.2f,  %.2f,  %.2f,  %.2f\n\n", row2.m128_f32[0], row2.m128_f32[1], row2.m128_f32[2], row2.m128_f32[3]);
    printf("row3:\t %.2f,  %.2f,  %.2f,  %.2f\n\n", row3.m128_f32[0], row3.m128_f32[1], row3.m128_f32[2], row3.m128_f32[3]);  _MM_TRANSPOSE4_PS(row0, row1, row2, row3);  printf("|**** After Matrix Transposition ****|\n\n");
    printf("row0:\t %.2f,  %.2f,  %.2f,  %.2f\n\n", row0.m128_f32[0], row0.m128_f32[1], row0.m128_f32[2], row0.m128_f32[3]);
    printf("row1:\t %.2f,  %.2f,  %.2f,  %.2f\n\n", row1.m128_f32[0], row1.m128_f32[1], row1.m128_f32[2], row1.m128_f32[3]);
    printf("row2:\t %.2f,  %.2f,  %.2f,  %.2f\n\n", row2.m128_f32[0], row2.m128_f32[1], row2.m128_f32[2], row2.m128_f32[3]);
    printf("row3:\t %.2f,  %.2f,  %.2f,  %.2f\n\n", row3.m128_f32[0], row3.m128_f32[1], row3.m128_f32[2], row3.m128_f32[3]);
}

测试结果:

  

SSE命令示例代码(整型、读写控制寄存器、混杂、矩阵变换)相关推荐

  1. SSE命令示例代码(算术、逻辑、比较)

    以下示例代码为原创,主要是为了测试SSE各种命令的实际效果,为了更好的理解各种命令. 1.  SSE的算术操作 // 测试SSE的算术操作 void TestSSEArith() { __m128 a ...

  2. SSE命令示例代码(转换、加载、置位、存储)

    1.   SSE的转换操作 // 测试SSE的转换操作 void TestSSEConvert() { // 浮点数组 __declspec(align(16)) float A[4] = { 5.3 ...

  3. linux 下tar怎样解压zip文件,linux下 zip解压 tar解压 gz解压 bz2等各种解压文件命令(示例代码)...

    简介这篇文章主要介绍了linux下 zip解压 tar解压 gz解压 bz2等各种解压文件命令(示例代码)以及相关的经验技巧,文章约6037字,浏览量504,点赞数7,值得推荐! .tar 解包:ta ...

  4. c语言实现pwd,20155222 c语言实现pwd命令(示例代码)

    20155222 c语言实现linux的pwd命令 1.学习pwd命令在Linux层次结构中,用户可以在被授权的任意目录下利用mkdir命令创建新目录,也可以利用cd命令从一个目录转换到另一个目录.然 ...

  5. linux上传文件操作,每天一个linux命令(文件上传下载文件操作):【转载】gzip命令(示例代码)...

    减少文件大小有两个明显的好处,一是可以减少存储空间,二是通过网络传输文件时,可以减少传输的时间.gzip是在Linux系统中经常使用的一个对文件进行压缩和解压缩的命令,既方便又好用.gzip不仅可以用 ...

  6. linux系统的ftp命令大全,linux系统ftp命令(示例代码)

    先来一段简单的ftp 下载脚本 ftp -i -n< open 14.2.33.211 user etl etl cd /etlfile/ftpfile lcd /etlfile/getfile ...

  7. linux 内存清理 释放命令,linux 内存清理释放命令(示例代码)

    linux 内存清理/释放命令 1.清理前内存使用情况 free -m 2.开始清理 echo 1 > /proc/sys/vm/drop_caches 3.清理后内存使用情况 free -m ...

  8. c语言有效的预处理命令,9、C语言之预处理命令(示例代码)

    预处理命令 基本概念:ANSI C标准规定可以在C源程序中加入一些"预处理命令",以改进程序设计环境,提高编程效率. 这些预处理命令是由ANSI C同一规定的,但是它们不是C语言本 ...

  9. linux 怎样清理内存,linux清理内存命令(示例代码)

    1.清理前内存使用情况 free -m 2.开始清理 echo 1 > /proc/sys/vm/drop_caches 3.清理后内存使用情况 free -m 4.完成! 查看内存条数命令: ...

最新文章

  1. layui一个表格中怎么接两个接口的值_layer学习笔记之table表格引入数据实现分页...
  2. 华为又一重拳!全球首款5G基站核心芯片“天罡”发布!
  3. 实战:使用OpenCV+Python+dlib为人脸生成口罩
  4. 【两行命令】R语言读取excel数据
  5. AutoPostBack与AutoComplete介绍
  6. 我在百度运维的成长经历 之五
  7. 网络安全与管理精讲视频笔记10-Windows隧道模式IPSec配置实验演示
  8. 数字调制解调—扩频通信和伪码同步
  9. 台式电脑桌面没有计算机图标,电脑桌面上“我的电脑”的图标没了怎么办
  10. 恢复有道词典单词记录本的几种方法(非完美)
  11. Vue开发环境的搭建
  12. domain adaptation论文记录
  13. Mac 连接不上Mysql数据库的解决方案
  14. GooglePlay区分推荐来源
  15. 【教程】怎样在PC查看动漫之家(DMZJ)不能观看漫画
  16. 计算机网络概述 网络的体系与标准化组织
  17. Windows_COM编程
  18. DirectIO(O_DIRECT) 详解
  19. 探索云原生技术之容器编排引擎-Kubernetes/K8S详解(6)
  20. [Java] 用java来突破一下人类极限

热门文章

  1. leetcode算法题--二叉树中和为某一值的路径
  2. 常见网络加速技术浅谈(二)
  3. Jmeter接口测试进阶
  4. wap问答系统工作总结
  5. Oracle 12c 简单的jdbc使用
  6. Codeforces Round #333 (Div. 2) C. The Two Routes flyod
  7. maven 使用 问题记录
  8. poj 2763 Housewife Wind
  9. 在Makefile中的 .PHONY 是做什么的?
  10. WindowsPhone7真机部署和调试程序