Dev*_*X10 4 c c++ intrinsics avx immediate-operand
我有一个关于 AVX_mm256_blend_pd功能的问题。
我想优化我大量使用该_mm256_blendv_pd函数的代码。不幸的是,这具有相当高的延迟和低吞吐量。该函数将三个变量作为输入__m256d,其中最后一个变量表示用于从前 2 个变量中进行选择的掩码。
我发现了另一个函数(_mm256_blend_pd),它采用位掩码而不是__m256d变量作为掩码。当掩码是静态时,我可以简单地传递类似 0b0111从第一个变量中获取第一个元素和第二个变量中的最后 3 个元素的内容。然而,在我的例子中,掩码是使用_mm_cmp_pd返回__m256d变量的函数计算的。我发现我可以用来_mm256_movemask_pd从掩码返回一个 int ,但是当将其传递到函数中时_mm256_blend_pd我收到一个 error error: the last argument must be a 4-bit immediate。
有没有办法使用前 4 位来传递这个整数?或者是否有另一个类似于 movemask 的功能可以让我使用_mm256_blend_pd?或者我可以使用另一种方法来避免使用 cmp、movemask 和混合,这对于这个用例来说会更有效?
_mm256_blend_pd是内部函数,vblendpd它将其控制操作数作为立即常量,嵌入到指令的机器代码中。(这就是汇编/机器代码术语中“立即”的含义。)
在 C++ 术语中,控制 arg 必须如此,constexpr以便编译器可以在编译时将其嵌入到指令中。您不能将它用于运行时变量混合。
不幸的是,像这样的变量混合指令vblendvpd速度较慢,但它们在 Skylake 上“仅”2 uop,具有 1 或 2 个周期延迟(取决于您测量关键路径所经过的输入)。(uops.info)。在 Skylake 上,这些微指令可以在 3 个矢量 ALU 端口中的任何一个上运行。(但在 Haswell/Broadwell 上更糟,仅限于端口 5,与洗牌竞争)。Zen 甚至可以将它们作为单个微指令运行。
对于一般情况来说,没有什么比这更好的了,直到 AVX512 使屏蔽成为您可以作为其他指令的一部分执行的一流操作,并为我们提供单微指令混合指令vblendmpd ymm0{k1}, ymm1, ymm2(根据屏蔽寄存器进行混合)。
在某些特殊情况下,您可以有效地_mm256_and_pd有条件地归零而不是混合,例如在之前将输入归零而add不是之后混合。
TL:DR:_mm256_blend_pd允许您在控件是编译时常量的特殊情况下使用更快的指令。
| 归档时间: |
|
| 查看次数: |
1776 次 |
| 最近记录: |