我希望找出包含8个16位无符号整数元素的两个向量中的最大值。
__m128i vi_A= _mm_loadu_si128(reinterpret_cast<const __m128i*>(&pSrc[0])); // 8 16-Bit Elements
__m128i vi_B= _mm_loadu_si128(reinterpret_cast<const __m128i*>(&pSrc1[0])); // 8 16-Bit Elements
__m128i vi_Max = _mm_max_epi16(vi_A,vi_B); //<-- Error
但是_mm_max_epi16
是一个有符号整数比较,这会导致溢出问题。
因此我尝试使用SSE4.1内置函数的无符号版本。
vi_Max = _mm_max_epu16(vi_A,vi_B);
但是我不允许使用SSE4.1内部函数,那么有什么高效的方法可以找到这些元素的最大值呢?
_mm_xor_si128
可能 比_mm_add_epi16
/_mm_sub_epi16
更快(吞吐量为0.33比0.5),但OP显然使用的是旧架构,所以情况可能并非如此。像往常一样,最好进行基准测试,但我猜差别不会很大。如上所述,溢出不是问题。还要注意,clang在代码生成期间将上述内容转换为使用_mm_xor_si128
,这非常酷。 - Paul Rpaddw
有明确定义的环绕语义,所以这不是问题。但我个人仍然认为XOR更清晰易懂。也许这只是一个愚蠢的主观偏好。XOR通常也能在比ADD/SUB更多的执行单元上运行,这也适用于旧架构。不过,Clang进行转换的功能确实非常酷。 - Cody Gray