c++ - 设置 SSE 寄存器中的最后或前 n 位

标签 c++ x86 sse simd intrinsics

我如何创建一个 __m128i 并设置了 n 个最高有效位(在整个 vector 中)?我需要它来屏蔽与计算相关的缓冲区部分。如果可能的话,解决方案应该没有分支,但这似乎很难实现

我该怎么做?

最佳答案

我将此添加为第二个答案,并将第一个答案留给历史兴趣。看起来你可以用 _mm_slli_epi64 做一些更有效的事情:

#include <emmintrin.h>
#include <stdio.h>

__m128i bit_mask(int n)
{
    __m128i v0 = _mm_set_epi64x(-1, -(n > 64)); // AND mask
    __m128i v1 = _mm_set_epi64x(-(n > 64), 0);  // OR mask
    __m128i v2 = _mm_slli_epi64(_mm_set1_epi64x(-1), (128 - n) & 63);
    v2 = _mm_and_si128(v2, v0);
    v2 = _mm_or_si128(v2, v1);
    return v2;
}

int main(int argc, char *argv[])
{
    int n = 36;

    if (argc > 1) n = atoi(argv[1]);

    printf("bit_mask(%3d) = %02vx\n", n, bit_mask(n));

    return 0;
}

测试:

$ gcc -Wall -msse2 sse_bit_mask.c
$ for n in 1 2 3 63 64 65 127 128 ; do ./a.out $n ; done
bit_mask(  1) = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80
bit_mask(  2) = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 c0
bit_mask(  3) = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 e0
bit_mask( 63) = 00 00 00 00 00 00 00 00 fe ff ff ff ff ff ff ff
bit_mask( 64) = 00 00 00 00 00 00 00 00 ff ff ff ff ff ff ff ff
bit_mask( 65) = 00 00 00 00 00 00 00 80 ff ff ff ff ff ff ff ff
bit_mask(127) = fe ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
bit_mask(128) = ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff

关于c++ - 设置 SSE 寄存器中的最后或前 n 位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22806319/

相关文章:

c++ - 我什么时候需要使用 std::async(std::launch::async, func()) 而不是 func()?

c++ - 使用 "auto"代替 std::vector<double>*

linux - 在汇编中查找数字是偶数/奇数

c++ - Visual Studio 和 GCC 中的参数传递

c++ - SSE/NEON查表优化

c++ - 我怎样才能在 opengl 中旋转我的对象

c - C 中的 Volatile,它在内部是如何工作的

linux - x86 程序集 : Before Making a System Call on Linux Should You Save All Registers?

c - simd 存储延迟

c++ - C++中存储分配后变量的值