登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

小波的世界

生活、教育、技术、旅游

 
 
 

日志

 
 

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

2014-09-10 20:01:37|  分类: SIMD |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
以下示例代码为原创,主要是为了测试SSE各种命令的实际效果,为了更好的理解各种命令。

1.  SSE的算术操作

// 测试SSE的算术操作
void TestSSEArith()
{
__m128 a;
a.m128_f32[0] = 10.0;
a.m128_f32[1] = -20.0;
a.m128_f32[2] = 30.0;
a.m128_f32[3] = -40.0;

__m128 b;
b.m128_f32[0] = 90.0;
b.m128_f32[1] = 75.0;
b.m128_f32[2] = -50.0;
b.m128_f32[3] = 35.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]);

// 加、减、乘、除
__m128 v1 = _mm_add_ss(a, b); // a[0] + b[0], a[1], a[2], a[3]
__m128 v2 = _mm_add_ps(a, b); // a[0] + b[0], a[1] + b[1], a[2] + b[2], a[3] + b[3]
__m128 v3 = _mm_sub_ss(a, b); // a[0] - b[0], a[1], a[2], a[3]
__m128 v4 = _mm_sub_ps(a, b); // a[0] - b[0], a[1] - b[1], a[2] - b[2], a[3] - b[3]
__m128 v5 = _mm_mul_ss(a, b); // a[0] * b[0], a[1], a[2], a[3]
__m128 v6 = _mm_mul_ps(a, b); // a[0] * b[0], a[1] * b[1], a[2] * b[2], a[3] * b[3]
__m128 v7 = _mm_div_ss(a, b); // a[0] / b[0], a[1], a[2], a[3]
__m128 v8 = _mm_div_ps(a, b); // a[0] / b[0], a[1] / b[1], a[2] / b[2], a[3] / b[3]

printf("v1 = a0 + b0: (%.2f, %.2f, %.2f, %.2f)\n\n", v1.m128_f32[0], v1.m128_f32[1], v1.m128_f32[2], v1.m128_f32[3]);
printf("v2 = a + b : (%.2f, %.2f, %.2f, %.2f)\n\n", v2.m128_f32[0], v2.m128_f32[1], v2.m128_f32[2], v2.m128_f32[3]);
printf("v3 = a0 - b0: (%.2f, %.2f, %.2f, %.2f)\n\n", v3.m128_f32[0], v3.m128_f32[1], v3.m128_f32[2], v3.m128_f32[3]);
printf("v4 = a - b : (%.2f, %.2f, %.2f, %.2f)\n\n", v4.m128_f32[0], v4.m128_f32[1], v4.m128_f32[2], v4.m128_f32[3]);
printf("v5 = a0 * b0: (%.2f, %.2f, %.2f, %.2f)\n\n", v5.m128_f32[0], v5.m128_f32[1], v5.m128_f32[2], v5.m128_f32[3]);
printf("v6 = a * b : (%.2f, %.2f, %.2f, %.2f)\n\n", v6.m128_f32[0], v6.m128_f32[1], v6.m128_f32[2], v6.m128_f32[3]);
printf("v7 = a0 / b0: (%.2f, %.2f, %.2f, %.2f)\n\n", v7.m128_f32[0], v7.m128_f32[1], v7.m128_f32[2], v7.m128_f32[3]);
printf("v8 = a / b : (%.2f, %.2f, %.2f, %.2f)\n\n", v8.m128_f32[0], v8.m128_f32[1], v8.m128_f32[2], v8.m128_f32[3]);

// 开方、倒数
__m128 v9 = _mm_sqrt_ss(a); // sqrt(a[0]), a[1], a[2], a[3]
__m128 v10 = _mm_sqrt_ps(a); // sqrt(a[0]), sqrt(a[1]), sqrt(a[2]), sqrt(a[3])
__m128 v11 = _mm_rcp_ss(a); // 1/a[0], a[1], a[2], a[3]
__m128 v12 = _mm_rcp_ps(a); // 1/a[0], 1/a[1], 1/a[2], 1/a[3]
__m128 v13 = _mm_rsqrt_ss(a); // 1/(sqrt(a[0])), a[1], a[2], a[3]
__m128 v14 = _mm_rsqrt_ps(a); // 1/(sqrt(a[0])), 1/(sqrt(a[1])), 1/(sqrt(a[2])), 1/(sqrt(a[3]))
printf("v9 = sqrt(a0) : (%.2f, %.2f, %.2f, %.2f)\n\n", v9.m128_f32[0], v9.m128_f32[1], v9.m128_f32[2], v9.m128_f32[3]);
printf("v10 = sqrt(a) : (%.2f, %.2f, %.2f, %.2f)\n\n", v10.m128_f32[0], v10.m128_f32[1], v10.m128_f32[2], v10.m128_f32[3]);
printf("v11 = 1 / a0 : (%.2f, %.2f, %.2f, %.2f)\n\n", v11.m128_f32[0], v11.m128_f32[1], v11.m128_f32[2], v11.m128_f32[3]);
printf("v12 = 1 / a : (%.2f, %.2f, %.2f, %.2f)\n\n", v12.m128_f32[0], v12.m128_f32[1], v12.m128_f32[2], v12.m128_f32[3]);
printf("v13 =1/sqrt(a0): (%.2f, %.2f, %.2f, %.2f)\n\n", v13.m128_f32[0], v13.m128_f32[1], v13.m128_f32[2], v13.m128_f32[3]);
printf("v14 =1/sqrt(a) : (%.2f, %.2f, %.2f, %.2f)\n\n", v14.m128_f32[0], v14.m128_f32[1], v14.m128_f32[2], v14.m128_f32[3]);

// 最大值、最小值
__m128 v15 = _mm_min_ss(a, b); // min(a[0], b[0]), a[1], a[2], a[3]
__m128 v16 = _mm_min_ps(a, b); // min(a[0], b[0]), min(a[1], b[1]), min(a[2], b[2]), min(a[3], b[3])
__m128 v17 = _mm_max_ss(a, b); // max(a[0], b[0]), a[1], a[2], a[3]
__m128 v18 = _mm_max_ps(a, b); // max(a[0], b[0]), max(a[1], b[1]), max(a[2], b[2]), max(a[3], b[3])
printf("v15 = min(a0, b0): (%.2f, %.2f, %.2f, %.2f)\n\n", v15.m128_f32[0], v15.m128_f32[1], v15.m128_f32[2], v15.m128_f32[3]);
printf("v16 = min(a, b) : (%.2f, %.2f, %.2f, %.2f)\n\n", v16.m128_f32[0], v16.m128_f32[1], v16.m128_f32[2], v16.m128_f32[3]);
printf("v17 = max(a0, b0): (%.2f, %.2f, %.2f, %.2f)\n\n", v17.m128_f32[0], v17.m128_f32[1], v17.m128_f32[2], v17.m128_f32[3]);
printf("v18 = max(a , b) : (%.2f, %.2f, %.2f, %.2f)\n\n", v18.m128_f32[0], v18.m128_f32[1], v18.m128_f32[2], v18.m128_f32[3]);
}

 测试结果:
   SSE命令示例代码(算术、逻辑、比较) - nkwavelet - 小波的世界
   Remark: 注意以上的 -1.#J 是因为负数开方出错导致的。

 2.  SSE的逻辑操作

// 测试SSE的逻辑操作
void TestSSELogic()
{
__m128 a;
a.m128_i32[0] = 0x96;
a.m128_i32[1] = 0x15;
a.m128_i32[2] = 0xB4;
a.m128_i32[3] = 0x7A;

__m128 b;
b.m128_i32[0] = 0x34;
b.m128_i32[1] = 0x57;
b.m128_i32[2] = 0x9C;
b.m128_i32[3] = 0xD1;

__m128 v1 = _mm_and_ps(a, b); // a & b
__m128 v2 = _mm_andnot_ps(a, b); // ~a & b
__m128 v3 = _mm_or_ps(a, b); // a | b
__m128 v4 = _mm_xor_ps(a, b); // a ^ b

printf("a : (0x%x, 0x%x, 0x%x, 0x%x)\n\n", a.m128_i32[0], a.m128_i32[1], a.m128_i32[2], a.m128_i32[3]);
printf("b : (0x%x, 0x%x, 0x%x, 0x%x)\n\n", b.m128_i32[0], b.m128_i32[1], b.m128_i32[2], b.m128_i32[3]);
printf("v1 = a & b: (%d, %d, %d, %d)\n\n", v1.m128_i32[0], v1.m128_i32[1], v1.m128_i32[2], v1.m128_i32[3]);
printf("v2 =~a & b: (%d, %d, %d, %d)\n\n", v2.m128_i32[0], v2.m128_i32[1], v2.m128_i32[2], v2.m128_i32[3]);
printf("v3 = a | b: (%d, %d, %d, %d)\n\n", v3.m128_i32[0], v3.m128_i32[1], v3.m128_i32[2], v3.m128_i32[3]);
printf("v4 = a ^ b: (%d, %d, %d, %d)\n\n", v4.m128_i32[0], v4.m128_i32[1], v4.m128_i32[2], v4.m128_i32[3]);
}

   测试结果:
   SSE命令示例代码(算术、逻辑、比较) - nkwavelet - 小波的世界

3.  SSE的比较操作

// 测试SSE的比较操作
void TestSSECompare()
{
__m128 a;
a.m128_i32[0] = 1200;
a.m128_i32[1] = 100;
a.m128_i32[2] = 350;
a.m128_i32[3] = 800;

__m128 b;
b.m128_i32[0] = 900;
b.m128_i32[1] = 400;
b.m128_i32[2] = 350;
b.m128_i32[3] = 600;

__m128 v[30];
v[0] = _mm_cmpeq_ss(a, b);
v[1] = _mm_cmpeq_ps(a, b);
v[2] = _mm_cmplt_ss(a, b);
v[3] = _mm_cmplt_ps(a, b);
v[4] = _mm_cmple_ss(a, b);
v[5] = _mm_cmple_ps(a, b);
v[6] = _mm_cmpgt_ss(a, b);
v[7] = _mm_cmpgt_ps(a, b);
v[8] = _mm_cmpge_ss(a, b);
v[9] = _mm_cmpge_ps(a, b);
v[10] = _mm_cmpneq_ss(a, b);
v[11] = _mm_cmpneq_ps(a, b);
v[12] = _mm_cmpnlt_ss(a, b);
v[13] = _mm_cmpnlt_ps(a, b);
v[14] = _mm_cmpnle_ss(a, b);
v[15] = _mm_cmpnle_ps(a, b);
v[16] = _mm_cmpngt_ss(a, b);
v[17] = _mm_cmpngt_ps(a, b);
v[18] = _mm_cmpnge_ss(a, b);
v[19] = _mm_cmpnge_ps(a, b);

v[20] = _mm_cmpord_ss(a, b);
v[21] = _mm_cmpord_ps(a, b);
v[22] = _mm_cmpunord_ss(a, b);
v[23] = _mm_cmpunord_ps(a, b);

int r[12];
r[0] = _mm_comieq_ss(a, b);
r[1] = _mm_comilt_ss(a, b);
r[2] = _mm_comile_ss(a, b);
r[3] = _mm_comigt_ss(a, b);
r[4] = _mm_comige_ss(a, b);
r[5] = _mm_comineq_ss(a, b);
r[6] = _mm_ucomieq_ss(a, b);
r[7] = _mm_ucomilt_ss(a, b);
r[8] = _mm_ucomile_ss(a, b);
r[9] = _mm_ucomigt_ss(a, b);
r[10] = _mm_ucomige_ss(a, b);
r[11] = _mm_ucomineq_ss(a, b);

for(int i = 0; i < 24; i += 2)
{
printf("v[%2d]: (%d, %d, %d, %d)\t v[%2d]: (%d, %d, %d, %d)\n", i, v[i].m128_i32[0], v[i].m128_i32[1], v[i].m128_i32[2], 

v[i].m128_i32[3], i+1, v[i+1].m128_i32[0], v[i+1].m128_i32[1], v[i+1].m128_i32[2], v[i+1].m128_i32[3]);
}
printf("\n");
for(int i = 0; i < 12; i += 4)
printf("r[%2d]: %d\t r[%2d]: %d\t r[%2d]: %d\t r[%2d]: %d\n", i, r[i], i+1, r[i+1], i+2, r[i+2], i+3, r[i+3]);
}

 测试结果:
  SSE命令示例代码(算术、逻辑、比较) - nkwavelet - 小波的世界
  评论这张
 
阅读(596)| 评论(0)

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018