gpt4 book ai didi

performance - 将位向量转换为一位

转载 作者:行者123 更新时间:2023-12-04 02:57:08 25 4
gpt4 key购买 nike

有没有一种有效的方法可以为非零无符号整数值获取 0x00000001 或 0xFFFFFFFF,而在没有分支的情况下获取 0 为零?

我想测试几个面具并基于它创建另一个面具。基本上,我想优化以下代码:

unsigned getMask(unsigned x, unsigned masks[4])
{
return (x & masks[0] ? 1 : 0) | (x & masks[1] ? 2 : 0) |
(x & masks[2] ? 4 : 0) | (x & masks[3] ? 8 : 0);
}

我知道一些优化编译器可以处理这个问题,但即使是这样,他们究竟是如何做到的?我查看了 Bit twiddling hacks 页面,但只找到了使用 bool 条件的条件设置/清除掩码的描述,因此转换来自 intbool应该在方法之外完成。

如果没有通用的方法来解决这个问题,我如何使用 x86 汇编代码有效地做到这一点?

最佳答案

x86 SSE2 可以通过几条指令做到这一点,最重要的是 movmskps 它将 SIMD 向量的每个 4 字节元素的最高位提取为整数位图。

Intel's intrinsics guide还不错,另见SSE tag wiki

#include <immintrin.h>

static inline
unsigned getMask(unsigned x, unsigned masks[4])
{
__m128i vx = _mm_set1_epi32(x);
__m128i vm = _mm_load_si128(masks); // or loadu if this can inline where masks[] isn't aligned

__m128i and = _mm_and_si128(vx, vm);

__m128i eqzero = _mm_cmpeq_epi32(and, _mm_setzero_si128()); // vector of 0 or -1 elems
unsigned zeromask = _mm_movemask_ps(_mm_castsi128_ps(eqzero));
return zeromask ^ 0xf; // flip the low 4 bits
}

在 AVX512 之前,没有 SIMD cmpneq ,所以最好的选择是提取掩码后的标量异或。 (我们只想翻转低 4 位,而不是所有的都带有 NOT。)

关于performance - 将位向量转换为一位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20172649/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com