gpt4 book ai didi

c - 使用 AVX 内在函数对 __m512i 中的 8 位整数求和

转载 作者:太空宇宙 更新时间:2023-11-04 06:11:29 25 4
gpt4 key购买 nike

AVX512 为我们提供了内在函数来对 __mm512 vector 中的所有单元格求和。然而,他们的一些对应物丢失了:还没有 _mm512_reduce_add_epi8

_mm512_reduce_add_ps     //horizontal sum of 16 floats
_mm512_reduce_add_pd //horizontal sum of 8 doubles
_mm512_reduce_add_epi32 //horizontal sum of 16 32-bit integers
_mm512_reduce_add_epi64 //horizontal sum of 8 64-bit integers

基本上,我需要在以下代码片段中实现 MAGIC

__m512i all_ones = _mm512_set1_epi16(1);
short sum_of_ones = MAGIC(all_ones);
/* now sum_of_ones contains 32, the sum of 32 ones. */

最明显的方法是使用 _mm512_storeu_epi8 并将数组的元素加在一起,但这会很慢,而且它可能会使缓存无效。我想存在一种更快的方法。

还有实现 _mm512_reduce_add_epi16 的奖励积分。

最佳答案

首先,_mm512_reduce_add_epi64并不对应单条AVX512指令,而是生成一系列shuffle和additions。

要将 64 个 epu8 值减少到 8 个 epi64 值,通常使用 vpsadbw针对零 vector 的指令(SAD=绝对差之和),然后可以进一步减少:

long reduce_add_epu8(__m512i a)
{
return _mm512_reduce_add_epi64(_mm512_sad_epu8(a, _mm512_setzero_si512()));
}

在 Godbolt 上试试:https://godbolt.org/z/1rMiPH .不幸的是,如果与 _mm512_set1_epi16(1) 一起使用,GCC 和 Clang 似乎都无法优化该函数。

对于 epi8 而不是 epu8,您需要首先将 128 添加到每个元素(或与 0x80 异或),然后使用 减少它code>vpsadbw 并在末尾减去 64*128(或在每个中间 64 位结果上减去 8*128)。 [请注意,在此答案的先前版本中这是错误的]

对于 epi16,我建议查看 _mm512_reduce_add_epi32_mm512_reduce_add_epi64 生成什么指令,并从那里导出要执行的操作。


总的来说,正如@Mysticial 所建议的,这取决于您的上下文,减少的最佳方法是什么。例如,如果您有一个非常大的 int64 数组并且想要求和为 int64,您应该将它们按数据包方式加在一起,并且只在最后减少一个数据包到单个 int64

关于c - 使用 AVX 内在函数对 __m512i 中的 8 位整数求和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55296777/

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