如何有效地定义128位常量?

时间:2012-06-03 20:13:17

标签: c visual-studio optimization sse intrinsics

我正在使用MS Visual Studio中的SSE2指令集。我用它来用16位数据做一些计算。

假设我有8个值加载到SSE寄存器中。我想为所有这些添加一个常量(例如42)。以下是我希望我的代码看起来的方式。

__m128i values; // 8 values, 16 bits each
const __m128i my_const_42 = ???; // What should i write here?
values = _mm_add_epi16(values, my_const_2); // Add 42 to the 8 values

现在,我该如何定义常量?以下两种方式有效,但一种方法效率低下,另一方面很难看。

  1. my_const_42 = _mm_set_epi16(42, 42, 42, 42, 42, 42, 42, 42) - 编译器为" build"生成8个命令。常数
  2. my_const_42 = {42, 0, 42, 0, 42, 0, 42, 0, 42, 0, 42, 0, 42, 0, 42, 0} - 很难理解发生了什么;将42更改为例如-42并非无足轻重
  3. 有没有办法更方便地表达128位常数?

2 个答案:

答案 0 :(得分:8)

百分之九十的战斗是找到正确的内在。 MSDN Library组织得非常好,从this page开始。从那里,向下钻取:

  • 您知道要使用“MMX,SSE和SSE2 Intrinsics”,请点击该链接
  • 您知道要使用“Streaming SIMD Extensions 2”,请点击该链接
  • 下一个有吸引力的链接是“整数内存和初始化”,因为您不需要浮点
  • 您将获得两个相关链接,即加载和设置操作
  • 加载只会让你找到你已找到的那些

设置为黄金,弹出弹出_mm_set1_epi16 (short w)

答案 1 :(得分:3)

关于在SSE(或NEON)中创建常量的注意事项。与指令执行相比,从内存加载数据非常慢。如果你需要一个可以通过代码创建的常量,那么这是更快的选择。以下是通过代码创建的常量的一些示例:

 xmmTemp = _mm_cmpeq_epi16(xmmA, xmmA); // FFFF
 xmmTemp = _mm_slli_epi16 (mmxTemp, 7); // now it has 0xFF80 (-128)

 xmmTemp = _mm_cmpeq_epi16(xmmA, xmmA); // FFFF
 xmmTemp = _mm_slli_epi16 (mmxTemp, 15); // 0x8000
 xmmTemp = _mm_srli_epi16 (mmxTemp, 11); // 0x10 (positive 16)