gpt4 book ai didi

assembly - 有没有办法在 x86 上使用 MMX/SSE 减去压缩的无符号双字,饱和?

转载 作者:行者123 更新时间:2023-12-04 21:02:27 24 4
gpt4 key购买 nike

我一直在看 MMX/SSE,我想知道。有用于无符号字节和字的压缩、饱和减法的指令,但没有双字的指令。

有没有办法做我想做的事,或者如果没有,为什么没有?

最佳答案

如果您有可用的 SSE4.1,我认为您不会比使用@harold 建议的 pmaxud + psubd 方法更好。对于 AVX2,您当然也可以使用相应的 256 位变体。

__m128i subs_epu32_sse4(__m128i a, __m128i b){
__m128i mx = _mm_max_epu32(a,b);
return _mm_sub_epi32(mx, b);
}

如果没有 SSE4.1,您需要以某种方式比较两个参数。不幸的是,没有 epu32 比较(不是在 AVX512 之前),但是您可以通过首先将 0x80000000(在这种情况下相当于异或运算)添加到两个参数来模拟:
__m128i cmpgt_epu32(__m128i a, __m128i b) {
const __m128i highest = _mm_set1_epi32(0x80000000);
return _mm_cmpgt_epi32(_mm_xor_si128(a,highest),_mm_xor_si128(b,highest));
}

__m128i subs_epu32(__m128i a, __m128i b){
__m128i not_saturated = cmpgt_epu32(a,b);
return _mm_and_si128(not_saturated, _mm_sub_epi32(a,b));
}

在某些情况下,最好通过对最高位进行一些位处理并使用移位将其广播到每一位来替换比较(这将替换 pcmpgtd 和三个位逻辑操作(并且必须至少加载一次 0x80000000) ) 通过 psrad 和五个位逻辑运算):
__m128i subs_epu32_(__m128i a, __m128i b) {
__m128i r = _mm_sub_epi32(a,b);
__m128i c = (~a & b) | (r & ~(a^b)); // works with gcc/clang. Replace by corresponding intrinsics, if necessary (note that `andnot` is a single instruction)
return _mm_srai_epi32(c,31) & r;
}

Godbolt-Link,还包括 adds_epu32 变体: https://godbolt.org/z/n4qaW1
奇怪的是,对于非 SSE4.1 变体,clang 需要比 gcc 更多的寄存器副本。另一方面,当使用 SSE4.1 编译时,clang 发现 pmaxud 变体的 cmpgt_epu32 优化: https://godbolt.org/z/3o5KCm

关于assembly - 有没有办法在 x86 上使用 MMX/SSE 减去压缩的无符号双字,饱和?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56526082/

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