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

1.   SSE的转换操作

// 测试SSE的转换操作 void TestSSEConvert() { // 浮点数组 __declspec(align(16)) float A[4] = { 5.35, 10.70, 16.05, 21.40 }; __declspec(align(16)) float B[4] = { 5.75, 11.50, 17.25, -25.3 }; __m128 *p = (__m128 *)A; __m128 *q = (__m128 *)B; __m128 a = p[0]; __m128 b = q[0]; printf("a: (%.2f, %.2f, %.2f, %.2f)\t b: (%.2f, %.2f, %.2f, %.2f)\n\n", p->m128_f32[0], p->m128_f32[1], p->m128_f32[2], p->m128_f32[3], q->m128_f32[0], q->m128_f32[1], q->m128_f32[2], q->m128_f32[3]); int v1 = _mm_cvtss_si32(a); int v2 = _mm_cvtss_si32(b); int v3 = _mm_cvttss_si32(a); int v4 = _mm_cvttss_si32(b); printf("(v1, v2, v3, v4): (%d, %d, %d, %d)\n\n", v1, v2, v3, v4); //__int64 v5 = _mm_cvtss_si64(a); //__int64 v6 = _mm_cvttss_si64(a); __m64 v5 = _mm_cvtps_pi32(a); __m64 v6 = _mm_cvttps_pi32(a); printf("v5: (%d, %d)\t v6: (%d, %d)\n\n", v5.m64_i32[0], v5.m64_i32[1], v6.m64_i32[0], v6.m64_i32[1]); //__m128 v7 = _mm_cvtsi64_ss(a, 123); __m128 v7 = _mm_cvtsi32_ss(a, 123); __m128 v8 = _mm_cvtpi32_ps(a, v5); 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]); __m64 v9 = _mm_cvtps_pi16(b); __m128 v10 = _mm_cvtpi16_ps(v9); __m128 v11 = _mm_cvtpu16_ps(v9); printf("v9: (%d, %d, %d, %d)\n\n", v9.m64_i16[0], v9.m64_i16[1], v9.m64_i16[2], v9.m64_i16[3]); printf("v10: (%.2f, %.2f, %.2f, %.2f)\n\n", v10.m128_f32[0], v10.m128_f32[1], v10.m128_f32[2], v10.m128_f32[3]); printf("v11: (%.2f, %.2f, %.2f, %.2f)\n\n", v11.m128_f32[0], v11.m128_f32[1], v11.m128_f32[2], v11.m128_f32[3]); __m64 temp; temp.m64_i8[0] = -1; temp.m64_i8[1] = 2; temp.m64_i8[2] = -3; temp.m64_i8[3] = 4; __m128 v12 = _mm_cvtpi8_ps(temp); __m128 v13 = _mm_cvtpu8_ps(temp); printf("v12: (%.2f, %.2f, %.2f, %.2f)\n\n", v12.m128_f32[0], v12.m128_f32[1], v12.m128_f32[2], v12.m128_f32[3]); printf("v13: (%.2f, %.2f, %.2f, %.2f)\n\n", v13.m128_f32[0], v13.m128_f32[1], v13.m128_f32[2], v13.m128_f32[3]); __m64 a1, a2; a1.m64_i32[0] = -120; a1.m64_i32[1] = 120; a2.m64_i32[0] = 256; a2.m64_i32[1] = -256; __m128 v14 = _mm_cvtpi32x2_ps(a1, a2); __m64 v15 = _mm_cvtps_pi16(v14); printf("v14: (%.2f, %.2f, %.2f, %.2f)\n\n", v14.m128_f32[0], v14.m128_f32[1], v14.m128_f32[2], v14.m128_f32[3]); printf("v15: (%d, %d, %d, %d)\n\n", v15.m64_i16[0], v15.m64_i16[1], v15.m64_i16[2], v15.m64_i16[3]); float f = _mm_cvtss_f32(a); printf("_mm_cvtss_f32(a) = %.2f\n\n", f); __m64 v16 = _mm_cvtps_pi8(v14); printf("v16: (%d, %d, %d, %d)\n\n", v16.m64_i8[0], v16.m64_i8[1], v16.m64_i8[2], v16.m64_i8[3]); }

   测试结果:
   SSE命令示例代码 - nkwavelet - 小波的世界
   Remark:  由于一些奇怪的原因,上面出现 -1.#J 的地方是显示错误,分别纠正如下:
     1. v7   中的  -1.#J 实为 21.40
     2. v10  中的  -1.#J 实为 -25.00
     3. v12  中的  -1.#J 实为 4.00
     4. v14 中的 -1.#J 实为 -256.00

2.  SSE的加载操作

// 测试SSE加载操作 void TestSSELoad() { // 浮点数组 __declspec(align(16)) float A[2] = { 5.35, 10.70 }; const __m64 *p = (const __m64 *)A; printf("(p0, p1): (%.2f, %.2f)\n\n", p->m64_f32[0], p->m64_f32[1]); __m128 a; a.m128_f32[0] = 80.45; a.m128_f32[1] = 85.55; a.m128_f32[2] = 90.65; a.m128_f32[3] = 95.75; __m128 v1 = _mm_loadh_pi(a, p); __m128 v2 = _mm_loadl_pi(a, p); 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]); const float f = 100.85; const float *q = &f; __m128 v3 = _mm_load_ss(q); __m128 v4 = _mm_load1_ps(q); 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]); __declspec(align(16)) const float r[4] = {1.11, 2.22, 3.33, 4.44}; __m128 v5 = _mm_loadu_ps(r); __m128 v6 = _mm_loadr_ps(r); // 注意此处地址r必须16字节对齐 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]); }

    测试结果:
    SSE命令示例代码 - nkwavelet - 小波的世界

3.   SSE的置位操作

// 测试SSE置位操作 void TestSSESet() { __m128 v0 = _mm_setzero_ps(); __m128 v1 = _mm_set_ss(3.55); __m128 v2 = _mm_set1_ps(3.55); __m128 v3 = _mm_set_ps(1.11, 2.22, 3.33, 4.44); __m128 v4 = _mm_setr_ps(1.11, 2.22, 3.33, 4.44); printf("v0: (%.2f, %.2f, %.2f, %.2f)\n\n", v0.m128_f32[0], v0.m128_f32[1], v0.m128_f32[2], v0.m128_f32[3]); 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]); }

测试结果:
SSE命令示例代码 - nkwavelet - 小波的世界
 
4.   SSE的存储操作

// 测试SSE存储操作 void TestSSEStore() { __m128 a; a.m128_f32[0] = 80.45; a.m128_f32[1] = 85.55; a.m128_f32[2] = 90.65; a.m128_f32[3] = 95.75; __declspec(align(16)) float A[2] = { 0 }; __declspec(align(16)) float B[2] = { 0 }; __m64 *p = (__m64 *)A; __m64 *q = (__m64 *)B; _mm_storeh_pi(p, a); _mm_storel_pi(q, a); printf("(p0, p1): (%.2f, %.2f)\n\n", p->m64_f32[0], p->m64_f32[1]); printf("(q0, q1): (%.2f, %.2f)\n\n", q->m64_f32[0], q->m64_f32[1]); __declspec(align(16)) float f[4] = { 0 }; _mm_store_ss(&f[0], a); printf("f[0]: %.2f\n\n", f[0]); _mm_store1_ps(f, a); printf("f: (%.2f, %.2f, %.2f, %.2f)\n\n", f[0], f[1], f[2], f[3]); _mm_store_ps(f, a); printf("f: (%.2f, %.2f, %.2f, %.2f)\n\n", f[0], f[1], f[2], f[3]); float g[4] = { 0 }; _mm_storeu_ps(g, a); printf("g: (%.2f, %.2f, %.2f, %.2f)\n\n", f[0], f[1], f[2], f[3]); _mm_storer_ps(f, a); printf("f: (%.2f, %.2f, %.2f, %.2f)\n\n", f[0], f[1], f[2], f[3]); }

   测试结果:
    SSE命令示例代码 - nkwavelet - 小波的世界
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值