【问题标题】:SSE integer 2^n powers of 2 for 32-bit integers without AVX2SSE 整数 2 的 2^n 次方,用于不带 AVX2 的 32 位整数
【发布时间】:2019-12-18 15:12:09
【问题描述】:

我找不到用于计算 32 位整数向量 __m128i 的 SSE 指令。

是否有执行以下伪代码的指令或函数?

__m128i power_of_two(__m128i b) {
    __m128 r;
    for (int i = 0; i < 4; i++)
        r[i] = 1 << b[i];
    return r;
}

_mm_sll_epi32 指令只计算r[i] = a[i] &lt;&lt; b[0]

【问题讨论】:

  • 每个元素的移位计数在AVX2 _mm_sllv_epi32 之前不存在。如果你不能只使用它,你必须模仿它,例如拆包和混合 (SSE2 shift by vector)。或者对于具有不同但恒定的移位计数的右移位,乘以并移位Shifting 4 integers right by different values SIMD
  • 对于要移动的值是常量1 的情况,x86 可以非常有效地处理标量(bts reg, reg 给定一个归零的目标)。但是使用 SSSE3,您也许可以将 pshufb 构建为查找表。如果您的计数始终为&lt;= 7(或者可能是&lt;= 15,还有更多工作),那么pshufb 是完美的。如果所有 4 个计数总是彼此靠近(前导位相同),那么您可以将计数分成低字节中 pshufb 的字节内位,然后是带有共同前缀的 _mm_sll_epi32 它们都分享。 (所以 AND / ANDN 将它们分开)。
  • 这也有一个浮动黑客
  • @harold:哦,对了!偏置计数并将其填充到指数字段中,然后将该 FP 位模式转换为整数。如果您没有 count &lt; 8 之类的任何限制,这可能最适合吞吐量。

标签: c++ x86 sse simd intrinsics


【解决方案1】:

在 AVX2 之前没有单条指令,但即使只有 SSE2,也有一个技巧滥用浮点格式来生成 2 的幂,方法是使用整数运算生成指数字段,然后将其从浮点数转换为整数.可能有更快的选择。

__m128i power_of_two(__m128i b) {
    __m128i exp = _mm_add_epi32(b, _mm_set1_epi32(127));
    __m128 f = _mm_castsi128_ps(_mm_slli_epi32(exp, 23));
    return _mm_cvtps_epi32(f);
}

【讨论】:

  • 谢谢。我需要更频繁地考虑 SSE 的浮动技巧。
猜你喜欢
  • 1970-01-01
  • 2013-07-25
  • 2012-05-17
  • 1970-01-01
  • 1970-01-01
  • 2015-07-29
  • 2023-03-19
  • 1970-01-01
  • 2012-03-16
相关资源
最近更新 更多