You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何对__m128i寄存器各元素执行不同位数的右移操作

Variable Right Shifts for __m128i Elements

Great question! Since you already have variable left shifts sorted out with multiplication, variable right shifts are actually simpler thanks to dedicated SIMD instructions—no messy division workarounds needed (which are slower and behave differently for signed values anyway).

Key Background

Unlike left shifts (which map cleanly to multiplication by powers of two), right shifts come in two flavors:

  • Logical right shift: For unsigned integers, fills empty high bits with 0.
  • Arithmetic right shift: For signed integers, fills empty high bits with the original sign bit (preserving negative values).

Intel's SIMD instruction set has dedicated variable-shift instructions for both cases, which let you shift each element in a __m128i by a different number of bits, just like your multiplication approach for left shifts.

Solution Code

Here's the direct equivalent to your left-shift example, for both unsigned and signed 32-bit elements:

// Assume R is your input __m128i with 4x32-bit integers
__m128i shift_counts = _mm_set_epi32(8, 4, 2, 1); // Same shift values as your left-shift multipliers

// Unsigned logical right shift (each element shifts right by its corresponding count, fills with 0)
__m128i right_vshift_unsigned = _mm_srlv_epi32(R, shift_counts);

// Signed arithmetic right shift (preserves sign for negative numbers)
__m128i right_vshift_signed = _mm_srav_epi32(R, shift_counts);

Important Notes

  1. Instruction Set Support: These instructions (_mm_srlv_epi32 and _mm_srav_epi32) are part of the SSSE3 extension. Make sure to compile with the appropriate flags:
    • GCC/Clang: Add -mssse3
    • MSVC: Use /arch:SSSE3 (or higher, like /arch:AVX2 which includes SSSE3)
  2. Element Size Flexibility: If you're working with 16-bit or 8-bit elements instead of 32-bit, use the corresponding instructions:
    • 16-bit: _mm_srlv_epi16 (unsigned), _mm_srav_epi16 (signed)
    • 8-bit: _mm_srlv_epi8 (unsigned), _mm_srav_epi8 (signed)
  3. Why Not Division?: While you could use division by powers of two for unsigned right shifts, it's slower than dedicated shift instructions. For signed values, division rounds towards zero instead of towards negative infinity (which is what arithmetic right shift does), leading to incorrect results for negative numbers.

内容的提问来源于stack exchange,提问作者Hadi Ranjbar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:53:45