vextracti128和vextractf128有什么区别?

时间:2013-09-25 05:22:02

标签: x86 simd avx avx2

vextracti128vextractf128具有相同的功能,参数和返回值。另外一个是AVX指令集,而另一个是AVX2。有什么不同?

2 个答案:

答案 0 :(得分:11)

vextracti128vextractf128不仅具有相同的功能,参数和返回值。它们具有相同的指令长度。并且它们具有相同的吞吐量(根据Agner Fog的优化手册)。

不完全清楚的是它们的延迟值(具有依赖链的紧密循环中的性能)。指令本身的延迟是3个周期。但在阅读英特尔优化手册的2.1.3节(“执行引擎”)之后,我们可能会怀疑vextracti128在处理浮点数据时应该额外延迟1个时钟延迟,而vextractf128应该会额外延长1个时钟延迟使用整数数据时。测量表明这不是真的,延迟总是保持3个周期(至少对于Haswell处理器而言)。据我所知,优化手册中的任何地方都没有记录。

静止指令集只是处理器的接口。 Haswell是此接口的唯一实现,包含这两个指令(暂时)。我们可以忽略这些指令的实现(很可能)相同的事实。并按预期使用这些说明 - vextracti128表示整数数据,vextractf128表示FP数据。 (如果我们只需要在不执行任何int / FP操作的情况下重新排序数据,那么显而易见的选择是vextractf128,因为几个较旧的处理器支持它。经验表明,英特尔有时会降低下一代CPU中某些指令的性能,因此明智地遵守这些指令的亲和性,以避免将来出现任何可能的速度降级。

由于英特尔优化手册不是非常详细地描述了用于SIMD指令的int / FP域之间的关系,我已经做了一些测量(在Haswell上)并得到了一些有趣的结果:


随机指示

SSE整数和随机指令之间的任何转换都没有额外的延迟。并且SSE FP和shuffle指令之间的任何转换都没有额外的延迟。 (虽然我没有测试每条指令)。例如,您可以在两条FP指令之间插入pshufb这样的“明显整数”指令而不会有额外的延迟。在整数代码的中间插入shufpd也不会产生额外的延迟。

由于shuffle单位执行vextracti128vextractf128,因此它们也具有“无延迟”属性。

这可能对优化混合int + FP代码很有用。如果您需要将FP数据重新解释为整数并同时对寄存器进行洗牌,只需确保所有FP指令都在shuffle之前,并且所有整数指令都在它之后。


FP逻辑指令

andps和其他FP逻辑指令也具有忽略FP / int域的属性。

如果在FP代码中添加整数逻辑指令(如pand),则会产生额外的2个周期延迟(一个到达int域,另一个到达FP)。因此,SIMD FP代码的明显选择是andps。可以在整数代码的中间使用相同的andps而没有任何延迟。更好的是在int和FP指令之间使用这样的指令。有趣的是,FP逻辑指令使用与所有shuffle指令相同的端口号5。


注册访问

英特尔优化手册介绍了生产者和消费者微操作之间的旁路延迟。但它并没有说明微操作如何与寄存器相互作用。

这段代码每次迭代只需要3个时钟(正如vaddps所要求的那样):

    vxorps ymm7, ymm7, ymm7
_benchloop:
    vaddps ymm0, ymm0, ymm7
    jmp _benchloop

但是这个每次迭代需要2个时钟(比vpaddd需要多1个时钟):

    vpxor ymm7, ymm7, ymm7
_benchloop:
    vpaddd ymm0, ymm0, ymm7
    jmp _benchloop

这里唯一的区别是整数域而不是FP域的计算。要获得1个时钟/迭代,我们需要添加一条指令:

    vpxor ymm7, ymm7, ymm7
_benchloop:
    vpand ymm6, ymm7, ymm7
    vpaddd ymm0, ymm0, ymm6
    jmp _benchloop

提示:(1)存储在SIMD寄存器中的所有值都属于FP域,(2)从SIMD寄存器读取会使整数运算的延迟增加1。 (这里{ymm0,ymm6}和ymm7之间的区别在于ymm7存储在一些临时存储器中并且作为真正的“寄存器”工作,而ymm0和ymm6是临时的并且由内部CPU的互连状态而不是某些永久存储器表示,所以ymm0和ymm6不是“读”但只是在微操作之间传递。

答案 1 :(得分:3)

好问题 - 看起来AVX指令vextractf128适用于任何矢量类型(int,float,double),而AVX2指令vextracti128仅适用于int矢量。如果你有AVX2和整数向量,我推荐使用后者,以防它在某些情况下提供更好的性能,否则使用前者。