欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

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

发布时间:2025/7/25 42 豆豆
生活随笔 收集整理的这篇文章主要介绍了 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]); }

   测试结果:        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]); }

   测试结果:    

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]); }

测试结果:   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]); }

  测试结果:     《新程序员》:云原生和全面数字化实践50位技术专家共同创作,文字、视频、音频交互阅读

总结

以上是生活随笔为你收集整理的SSE命令示例代码(转换、加载、置位、存储)的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。