AVX2:U8绝对差

Posted

技术标签:

【中文标题】AVX2:U8绝对差【英文标题】:AVX2: U8 absolute difference 【发布时间】:2017-10-27 06:34:36 【问题描述】:

我是 AVX 的新手(来自 ARM NEON),对于 AVX 缺少许多 U8 算法,其中缺少绝对差异,我感到非常惊讶。

因此我不得不求助于max(a,b)-min(a,b) 的内联函数:

static inline __m256i _mm256_abd_epu8(__m256i a, __m256i b)

    return _mm256_sub_epi8(_mm256_max_epu8(a, b), _mm256_min_epu8(a, b));

我很好奇是否有更有效的方法来处理这个问题。

是的,我知道_mm256_sad_epu8,但我需要差异本身,而不是总和。

我很感激任何意见,AVX2 没问题,不考虑任何向后兼容性。

提前致谢。

【问题讨论】:

【参考方案1】:

我不知道仅使用 2 条或更少的指令来执行此操作的任何技巧。 (而且这个问题的 SSE 版本也没有更好的东西:Compute the absolute difference between unsigned integers using SSE)。它确实提到了我在这个答案中使用的饱和方法。


稍微在 Skylake 之前的版本上更好:用无符号饱和度减去两种方式,然后 OR 结果。 (对于每个元素,a-b 或 b-a 都饱和为零。)

_mm256_or_si256(_mm256_subs_epu8(a,b), _mm256_subs_epu8(b,a))

在 Haswell 上,pmin/pmaxpsub 仅在端口 1 或端口 5 上运行,但 por 可以在三个向量执行端口(0、1、5)中的任何一个上运行。

Skylake 添加了第三个向量整数加法器,因此该 uarch 没有区别。 (参见http://agner.org/optimize/ 和x86 标签wiki 中的其他链接,包括英特尔的优化手册。)

这在 Ryzen 上也稍微好一些,根据 Agner Fog 的测试,VPOR 可以在任何 P0123 上运行,但 PADD/PMIN 只能在 P013 上运行。 (Ryzen 将 256b 向量运算拆分为 2 个微指令,但它具有有用的吞吐量。它无法仅使用单微指令指令填充其 6 微指令宽的管道。)

可以在更多端口上运行的 Uop 等待其分配的端口(资源冲突)的可能性较小,因此您实际上更有可能获得 2 个周期的总延迟(从两个输入都准备好到输出准备好了)。如果存在对特定端口的竞争(例如端口 5,它在 Intel Haswell 及更高版本上具有唯一的 shuffle 单元),它们也不太可能导致吞吐量瓶颈。

【讨论】:

哇,我什至无法想象一个更全面的答案。正是我需要的。谢谢。 @Jake'Alquimista'LEE:干杯,我以为你会欣赏微架构的东西,所以我比其他方式更详细。 绝对!!!!现在我意识到我必须深入挖掘管道,而您提供的链接是天赐之物。 @Jake'Alquimista'LEE:我的其他一些答案有一些好东西。例如***.com/questions/45113527/…。还有一些我投票率最高的答案,尤其是***.com/questions/40354978/…

以上是关于AVX2:U8绝对差的主要内容,如果未能解决你的问题,请参考以下文章

使用 AVX2 支持编译并运行

AVX2 和 AVX-512 有啥区别?

AVX2 等效于 std::clamp

在 Mavericks 上编译 AVX2 程序

AVX2 基于面具的最有效打包方式是啥?

AVX2 基于面具的最有效打包方式是啥?