在英特尔内部函数(AVX)中使用混合指令

问题描述 投票:1回答:1

我对AVX _mm256_blend_pd功能有疑问。

我想在大量使用_mm256_blendv_pd函数的地方优化代码。不幸的是,这具有很高的延迟和低吞吐量。此函数将三个__m256d变量作为输入,其中最后一个代表用于从前两个变量中选择的掩码。

[我发现了另一个函数(_mm256_blend_pd),它使用位掩码而不是__m256d变量作为掩码。当掩码为静态时,我可以简单地传递0b0111之类的内容,以从第一个变量中获取第一个元素,并从第二个变量中获取最后3个元素。但是在我的情况下,掩码是使用_mm_cmp_pd函数计算的,该函数返回__m256d变量。我发现我可以使用_mm256_movemask_pd从掩码中返回一个int,但是将其传递给函数_mm256_blend_pd时会出现错误error: the last argument must be a 4-bit immediate

是否有一种方法可以使用前4位传递该整数?还是有另一个类似于movemask的功能允许我使用_mm256_blend_pd?还是我可以使用另一种方法来避免使用cmp,movemask和blend来提高此用例的效率?

c++ c intrinsics avx immediate-operand
1个回答
1
投票

_mm256_blend_pdvblendpd的内在函数,它将其控制操作数作为立即数,嵌入到指令的机器代码中。 (这就是“即时”在汇编/机器代码术语中的意思。)

在C ++中,控制arg必须为vblendpd,以便编译器可以在编译时将其嵌入到指令中。您不能将其用于运行时变量混合。

不幸的是,像constexpr这样的可变混合指令比较慢,但是它们在Skylake上仅“ 2”个微指令,具有1或2个周期的延迟(取决于您正在测量通过的关键路径)。 (vblendvpd)。在Skylake上,这些uops可以在3个矢量ALU端口中的任何一个上运行。 (不过,在Haswell / Broadwell上更糟,但仅限于端口5,并与shuffle竞争。) Zen甚至可以将它们作为单个uop运行。

在一般情况下,没有什么更好的方法,直到AVX512使掩蔽成为您可以作为其他指令一部分进行的一流操作,并为我们提供诸如uops.info之类的单uup混合指令(根据掩码寄存器进行混合)。

[在某些特殊情况下,您可以有效地vblendmpd ymm0{k1}, ymm1, ymm2有条件地为零而不是混合,例如将_mm256_and_pd之前的输入置零,而不是之后的混合。


TL:DR:add使您可以为控件is编译时常量的特殊情况使用更快的指令。

© www.soinside.com 2019 - 2024. All rights reserved.