【发布时间】:2015-01-09 20:43:31
【问题描述】:
如何在 512 位 AVX 寄存器中有效地使用浮点数执行水平加法(即将单个向量中的项目加在一起)?对于 128 位和 256 位寄存器,这可以使用 _mm_hadd_ps 和 _mm256_hadd_ps 完成,但没有 _mm512_hadd_ps。英特尔内在函数指南文档 _mm512_reduce_add_ps。它实际上并不对应于单个指令,但它的存在表明存在一种最佳方法,但它似乎没有在 GCC 最新快照附带的头文件中定义,我找不到它与谷歌。
我认为“hadd”可以用 _mm512_shuffle_ps 和 _mm512_add_ps 来模拟,或者我可以使用 _mm512_extractf32x4_ps 将一个 512 位寄存器分解为四个 128 位寄存器,但我想确保我不会错过更好的东西。
【问题讨论】:
-
你到底想用水平操作做什么?如果它是大型归约操作的结束,那么它甚至可能不是性能关键的。 (尽管如此,
_mm512_reduce_add_ps是为此目的而存在的,并编译为 shuffle 和 sum 的二进制减少。) -
我并不感到惊讶,因为 AVX-512 有点偏离标准的“双倍宽度”改进。操作已经被分割成 128 位或 256 位微指令,所以水平指令还没有多大意义。
-
@CoryNelson 更糟糕的是,水平指令在现有处理器上进行了微编码。所以他们已经很慢了。而且,水平矢量化的任务违反了 SIMD 范式并且无法扩展。
-
@Mystical 水平操作仅在
AMD Bulldozer/Piledriver/Steamroller上进行微编码 -
@MaratDukhan 根据 Agner Fog 的表格,它们还在 Prescott、Core 2、Nehalem、Sandy Bridge、Haswell、Atom 和 Via Nano 上进行了微编码。这几乎涵盖了其他所有内容。他没有关于K10的任何信息。 K8 的条目是空白的。
标签: simd intrinsics avx512