我需要执行以下两项操作:

float x[4];
float y[16];

// 1-to-4 broadcast
for ( int i = 0; i < 16; ++i )
    y[i] = x[i / 4];

// 4-to-1 reduce-add
for ( int i = 0; i < 16; ++i )
    x[i / 4] += y[i];

什么是有效的AVX-512实现?

#1楼 票数:2 已采纳

对于reduce-add,只需进行vmovshdup改组并添加( vmovshdup / vaddps / vpermilps imm8 / vaddps ),就像在x86上进行水平浮点矢量和的最快方法一样, 在每个128位通道中获取水平和,然后vpermps将所需的元素vpermps到底部。 或使用带有恒定掩码的vcompressps做相同的事情,还可以选择使用内存目标。

打包成单个向量后,您将拥有一个普通的SIMD 128位加法。

如果您的数组实际上大于16,则可以使用vpermt2ps而不是vpermps从两个源向量中的每一个获取第4个元素,从而将+=部分用于x[] 256位向量。 (或者再次与另一个改组合并为512位向量,但这可能会成为SKX上改组吞吐量的瓶颈)。

在SKX上, vpermt2ps仅为单个uop,吞吐量为1c /延迟为3c,因此对于其强大功能而言非常有效。 在KNL上,它的吞吐量为2c,比vpermps差,但也许仍然值得。 (KNL没有AVX512VL,但是如果需要,您(或编译器)可以将256位向量添加到x[] ,然后使用AVX1 vaddps ymm 。)

有关说明表,请参见https://agner.org/optimize/


对于负载:

这是在循环内完成还是反复进行? (即,您可以将随机控制向量保存在寄存器中吗?如果可以,则可以

  • 使用VBROADCASTF32X4 (用于加载端口的单个VBROADCASTF32X4执行128-> 512广播。
  • vpermilps zmm,zmm,zmm进行车道内混洗vpermilps zmm,zmm,zmm以在每个128位通道中广播不同的元素。 (必须与广播负载分开,因为内存源vpermilps可以具有m512m32bcst源。(指令通常具有其内存广播粒度=元素大小,不幸的是,在某些情况下,这样的情况根本没有) vpermilps将控制向量作为内存操作数,而不是源数据。)

这是好于vpermps zmm,zmm,zmm因为洗牌有1周周期的延迟,而不是3(在SKYLAKE微架构-avx512)。

即使在循环之外,加载随机播放控制向量仍可能是您最好的选择。

  ask by user2052436 translate from so

未解决问题?本站智能推荐:

1回复

AVX-512中的1-to-4广播和4-to-1压缩

我需要执行以下两项操作: 什么是有效的AVX-512实现?
1回复

模拟AVX-512掩码指令

根据文档,从AVX-512指令集上的gcc 4.9开始支持,但是我有gcc 4.8 。 我目前有类似这样的代码来汇总一个内存块(保证少于256个字节,因此不会有溢出的烦恼): 现在,浏览文档,如果剩下四个字节,我可以使用: (请注意,我找不到的任何地方都没有记录__mmask8
1回复

在 AVX512 中乘以不同的类型

我目前正在尝试将__m512d值与__m512i值相乘。 __m512d值为 ln(2),因此结果保存在另一个__m512d变量中。 但是,我无法在 avx512 中找到将双精度乘以整数的任何内在函数。 当我使用_mm512_castsi512_pd内在的__m512i ,我得到一个错误的值,所以
2回复

如何在编译时检测 SSE/SSE2/AVX/AVX2/AVX-512/AVX-128-FMA/KCVI 可用性?

我正在尝试优化一些矩阵计算,我想知道是否可以在编译时检测 SSE/SSE2/AVX/AVX2/AVX-512/AVX-128-FMA/KCVI [1]是否由编译器? 非常适合 GCC 和 Clang,但我只能使用其中之一进行管理。 我不确定这是否可行,也许我会使用我自己的宏,但我更喜欢检测它并要求
1回复

avx512中比较内在指令的不同语义?

使用sse2或avx比较操作返回所有零或全部的位掩码(例如_mm_cmpge_pd返回__m128d。 我找不到avx512的等价物。 比较操作似乎只返回短位掩码。 语义是否发生了根本变化,或者我遗漏了什么?
1回复

从 avx/sse 掩码到 avx512 掩码的“正确”方法是什么?

我有一些现有的 avx/sse 掩码,我用旧方法: 在某些情况下,将旧的 avx 代码与新的 avx512 代码混合时,我想将这些旧样式的掩码转换为新的 avx512 __mmask4或__mmask8类型。 我试过这个: 它似乎适用于普通的旧比较输出,但我认为它不会正确捕获可以与 sse
1回复

给定一个 int 偏移向量,如何使用 AVX512 内在函数收集单个字节?

我有一个基地址 (uint8_t*) 和一个包含 16 个偏移量的向量 (__m512i)。 我需要最终得到一个 __m128i,其中包含从 16 个不同的内存位置收集的 16 个字节。 至于现在我明白没有这样的原语,我能用的就是 这给了我一个 __m512i (j 是垃圾,V 是我感兴
1回复

有什么方法可以将基于AVX512 CPU intrinics的unsigned char转换为short?

我只是在Xeon Phi处理器中阅读AVX512的cpu内在函数集,但似乎sse中的传统数据类型转换方法在avx512中不起作用,所以我可以问问avx512中是否有任何类似的cpu集合可以转换未签名的char数组到短数据类型数组? 提前致谢!
1回复

_mm512_load_epi32和_mm512_load_si512有什么区别?

英特尔内在指南简单地说明了_mm512_load_epi32 : 从存储器加载[s] 512位(由16个打包的32位整数组成)到dst 那_mm512_load_si512 : 将[s] 512位整数数据从内存加载到dst中 这两者有什么区别? 文件不清楚。
2回复

矢量化 - 加速SSE,AVX和AVX2的预期

我正在使用以下处理器i7对MacOS上的矢量化进行基准测试: $ sysctl -n machdep.cpu.brand_string 我的MacBook Pro是2014年中期。 我尝试使用不同的标志选项进行矢量化:我感兴趣的3个是SSE,AVX和AVX2。 对