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

来源:互联网 发布:淘宝怎么看上架的时间 编辑:程序博客网 时间:2024/05/01 14:18
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]);}

  测试结果:
  SSE命令示例代码(整型指令) - nkwavelet - 小波的世界

2.  SSE的读写寄存器指令

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

  测试结果:
   SSE命令示例代码(整型、读写控制寄存器、混杂) - nkwavelet - 小波的世界
 
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 = 10int maskB = _mm_movemask_ps(b);// sign(b) : 0, 1, 0, 0 (从高到低), maskB = 4printf("maskA: %d\t maskB: %d\n", maskA, maskB);}

  测试结果:
  SSE命令示例代码(整型、读写控制寄存器、混杂) - nkwavelet - 小波的世界

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命令示例代码(整型、读写控制寄存器、混杂、矩阵变换) - nkwavelet - 小波的世界
 
0 0
原创粉丝点击