在AVX512中索引数组存储的最快方法?

问题描述

我的操作形式为:

for (I=0;I<31;I++)
{
 dst[index1[I]]=src1[I];
 dst[index2[I]]=src2[I];
}

所有数据数组都有128b个元素。 [编辑]

我不确定在AVX512中实现它的最佳方法是什么。我可以将源加载到zmm寄存器中,但此后我能做的最好的事情是使用提取和128b存储。有什么建议吗?

解决方法

在当前的CPU上,AVX-512分散指令不是非常快,在Skylake-X上每个时钟周期少于一个64位元素,在Ice Lake上仅超过1个qword /时钟 1 。 手动分散应该比用64位分散指令模拟128位分散更好,但是如果您好奇的话,可以对两种方法进行基准测试。

特别是如果索引可以在index1和index2之间重叠(碰撞),则几乎可以肯定4个独立的128位存储要比检查索引向量对之间的冲突好。请注意,从中分散4x个元素如果library(tidyverse) rdf1 <- Df_2 %>% left_join(Df_1,by = 'value') %>% group_by(ID.x) %>% mutate(keep = !any(is.na(ID.y))) %>% ungroup # > rdf1 # # A tibble: 6 x 4 # ID.x value ID.y keep # <chr> <chr> <chr> <lgl> # 1 y A x FALSE # 2 y B x FALSE # 3 y D NA FALSE # 4 z A x TRUE # 5 z B x TRUE # 6 z C x TRUE rdf1 %>% filter(keep) ,则src1和src2中的4x元素将给出不同的最终结果。按照原始的源顺序,该dst元素将得到idx1[1] == idx2[0],但是如果您不小心,它将得到src1[1]

使用128位元素,可能只进行512位加载,并通过src2[0](通过vmovdqu xmm / _mm512_castsi512_si128)和3x {{ 1}}(VEXTRACTI64x2)商店。

或256位加载和_mm_storeu_si128 + _mm512_extracti64x2_epi64存储。但是,如果在周围的代码中使用512位向量,则最好在此处使用它们;您已经在支付CPU频率和执行端口关闭费用。

如果可以让编译器执行64位索引数据加载,并用vmovdqu xmm / vextracti128分开32位一半,以节省内存加载/存储端口,那可能会很好。 。使用GNU C mov eax,edx可能是可行的。


脚注1 :例如在最佳情况下,Skylake-X上的shr rdx,32的吞吐量为每11个周期1个。或在冰湖上,每7个周期1个。 https://uops.info/

因此,每11个周期有4个128位存储。手动128位分散可能每2个周期至少存储1x 128位存储,甚至每个时钟1次。甚至在Ice Lake上,它有2个存储端口和 2个加载端口,以及更宽的前端,速度甚至更快。

对于前端来说,分散指令也有很多用法:分别在SKX或ICL上为26或19。


但只是为了好玩,模拟128位分散:

我们可以使用诸如typedef uint64_t aliasing_u64 __attribute((may_alias,aligned(4)));VPSCATTERDQ)这样的64位元素散点来模拟128位元素散点。如果您的索引需要为64位,则可以使用vpscatterdq zmm(VPSCATTERQQ),否则可以节省用于加载索引的内存带宽。

生成索引向量,该向量将连续的qword元素对存储到_mm512_i32scatter_epi64_mm512_i64scatter_epi64


散点图中的比例因子只能是1,2,4或8,与x86索引寻址模式相同。如果您可以将“索引”存储为字节偏移量而不是元素偏移量,则可能会提高效率。否则,您必须首先将每个索引输入向量加倍(通过将其自身添加)。

然后将其与增量副本(可能与index1[I]*2

交织)
index1[I]*2 + 1

https://godbolt.org/z/TxzjWz显示了它如何循环编译。 (默认情况下,clang会完全展开它。)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...