gpt4 book ai didi

x86 - SSE 乘法 16 x uint8_t

转载 作者:行者123 更新时间:2023-12-02 15:52:32 25 4
gpt4 key购买 nike

我想用 SSE4 将 __m128i 对象与 16 个无符号 8 位整数相乘,但我只能找到用于相乘 16 位整数的内在函数。有没有诸如_mm_mult_epi8之类的东西?

最佳答案

比 Marat 基于 Agner Fog's solution 的解决方案(可能)更快的方法:

不是分割高/低,而是分割奇数/偶数。这还有一个额外的好处,它可以与纯 SSE2 一起使用,而不需要 SSE4.1(对 OP 没有用,但对某些人来说是一个不错的额外好处)。如果您有 AVX2,我还添加了优化。从技术上讲,AVX2 优化仅适用于 SSE2 内在函数,但它比先左移再右移的解决方案慢。

__m128i mullo_epi8(__m128i a, __m128i b)
{
// unpack and multiply
__m128i dst_even = _mm_mullo_epi16(a, b);
__m128i dst_odd = _mm_mullo_epi16(_mm_srli_epi16(a, 8),_mm_srli_epi16(b, 8));
// repack
#ifdef __AVX2__
// only faster if have access to VPBROADCASTW
return _mm_or_si128(_mm_slli_epi16(dst_odd, 8), _mm_and_si128(dst_even, _mm_set1_epi16(0xFF)));
#else
return _mm_or_si128(_mm_slli_epi16(dst_odd, 8), _mm_srli_epi16(_mm_slli_epi16(dst_even,8), 8));
#endif
}

Agner 使用具有 SSE4.1 支持的 blendv_epi8 内在函数。

编辑:

有趣的是,在做了更多的反汇编工作(使用优化的构建)之后,至少我的两个实现被编译为完全相同的东西。针对“ivy-bridge”(AVX) 的反汇编示例。

vpmullw xmm2,xmm0,xmm1
vpsrlw xmm0,xmm0,0x8
vpsrlw xmm1,xmm1,0x8
vpmullw xmm0,xmm0,xmm1
vpsllw xmm0,xmm0,0x8
vpand xmm1,xmm2,XMMWORD PTR [rip+0x281]
vpor xmm0,xmm0,xmm1

它使用带有预编译的 128 位 xmm 常量的“AVX2 优化”版本。仅使用 SSE2 支持进行编译会产生类似的结果(尽管使用 SSE2 指令)。我怀疑 Agner Fog 的原始解决方案可能会针对同样的事情进行优化(如果没有的话那就太疯狂了)。不知道 Marat 的原始解决方案在优化构建中的比较如何,尽管对我来说,对所有更新于(包括 SSE2)的 x86 simd 扩展使用单一方法是相当不错的。

关于x86 - SSE 乘法 16 x uint8_t,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8193601/

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