如何解决avx512 跨步聚集,任意步幅
我知道在 AVX512 中,您可以执行步幅为 1、2、4、8 的跨步聚集。但是,如果我有一个可以在 10-1000 之间的任意步幅怎么办?步幅在编译时已知。我明白指令不会是瓶颈,内存可能会。 _mm512_set_ps 是最有效的方法吗?
解决方法
步幅为 1,2,4,8
不,没有特别的支持;也许您正在考虑 ARM/ARM64 NEON vld4
4 路去交错?
在 x86 中,您可以使用 1、2、4 或 8 作为vpgatherdd
/ vpgatherdps
的索引向量的比例因子,但如果您只想要每个第二个元素最好手动洗牌(例如,_mm512_permutex2var_ps
从 2 个输入向量中抓取备用浮点数),用一个宽负载获取许多有用的元素,而不是每个元素访问一次缓存。
但在您的情况下,最小步幅为 10,最多 2 个元素将来自相同的 16 x 32 位 512 位向量,并且步幅更宽,每个向量甚至没有一个。
因此您可以在循环中使用 vpgatherdps
和 _mm512_add_epi32(idx,_mm512_set1_epi32(16 * stride))
。 或者更好的是,使用固定的索引向量并增加基指针。您可以使用 _mm512_mullo_epi32(_mm512_setr_epi32(0,1,3,...,15),_mm512_set1_epi32(stride))
生成索引向量。由于浮点数为 4 个字节宽,因此在您的聚集中使用 4
的比例因子。
即使您需要处理巨大的数组,增加指针而不是向量元素可以避免对 64 位索引的任何需要,并最大限度地减少向量 uop 的数量。 (在当前 CPU 上使用 512 位向量时很有价值。)
IIRC,英特尔的优化手册有一节关于跨步加载以及手动收集与使用收集指令的权衡。向量越宽,收集指令就会变得相对越好(2/clock 负载吞吐量,但对于大多数 shuffle 来说只有 1/clock shuffle 吞吐量),所以特别是对于 512 位向量,使用 vector shuffle 可能是一个胜利。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。