2016-11-22 32 views
1

我正在使用AVX2 x86 256位SIMD扩展。我想要做一个32位整数成分明智的if-then-else指令。在英特尔文档中,这样的指令称为vblend。howto vblend for 32-bit integer?或者:为什么没有_mm256_blendv_epi32?

英特尔内部指南包含函数_mm256_blendv_epi8。这个功能几乎可以满足我的需求。唯一的问题是它与8位整数一起工作。不幸的是,文档中没有_mm256_blendv_epi32。我的第一个问题是:为什么这个功能不存在?我的第二个问题是:如何模仿它?

经过一番搜索后,我发现_mm256_blendv_ps这做我想要的32位浮点。此外,我发现了投射函数_mm256_castsi256_ps和_mm256_castps_si256,它们从整数转换为32位浮点数并返回。将这些一起给出:

inline __m256i _mm256_blendv_epi32 (__m256i a, __m256i b, __m256i mask){ 
    return _mm256_castps_si256( 
     _mm256_blendv_ps(
      _mm256_castsi256_ps(a), 
      _mm256_castsi256_ps(b), 
      _mm256_castsi256_ps(mask) 
     ) 
    ); 
} 

虽然这看起来像5层的功能,它们中的4只美化了管型和一个直接映射到处理器的指令。因此整个功能归结为一个处理器指令。

因此,真正的尴尬部分是似乎有一个32位的blendv,除了相应的内在缺失。

是否有一些边界情况下会失败?例如,当整数位模式恰好表示浮点数NAN时会发生什么? blendv干脆忽略这一点,还是会提高一些信号?

如果这个工程:我是正确,有8位,32位和64位blendv但16位blendv缺什么?

+0

你真的太过于复杂。只需将标志位复制到覆盖您的值的所有字节中,并使用_mm256_blendv_epi8'。如果你可以为你所有的32位整数生成一个0xffffffff的掩码,你已经拥有了你所需要的。 –

+0

@Mark随机我的代码依赖于blendv只检查最高位。我有32个真/假值编码在一个向量中。我在blendv之前使用shift来选择值。但我同意,使用cmpxx内在函数之一的结果时,blendv_epi8会完成这项工作。 –

+0

'blendvps'确实很安全,就像fp洗牌和移动一样。 – harold

回答

2

我的代码依赖于blendv只检查的最高位。

你有两个不错的选择:

  • 使用VBLENDVPS。所有演员都只是为了让编译器保持开心,并且VBLENDVPS将在一条指令中完全符合您的要求。

    然而,英特尔SNB-家族CPU具有1个周期的旁通延迟延迟转发整数结果给FP混合单元时,和另一1C延迟转发所述共混物的结果对于其他整数指令时。

有关旁路延迟等待时间的更多信息,请参见Agner Fog's microach guide。这就是他们不会为FP指令创建内部函数的原因,反之亦然。请注意,自从Sandybridge,FP洗牌不要有额外的延迟来转发/ PADDD指令。因此,如果PUNPCK *或PALIGNR不能完全按照您的要求进行操作,则SHUFPS是合并两个整数向量数据的好方法。 (对整数SHUFPS甚至可以在Nehalem上获得值得的价值,在这种情况下双方都有2c的惩罚)。

尝试两种方式和基准。无论哪种方式可能会更好,这取决于周围的代码。

与uop吞吐量/指令计数相比,延迟可能并不重要。另请注意,如果您只是将结果存储到内存中,那么存储指令并不关心数据来自哪个域。

但是,如果您将此用作长依赖链的一部分,那么可能需要额外的指令来避免混合数据的额外2个周期延迟。

请注意,如果掩码生成位于关键路径上,那么VPSRAD的1个周期延迟等同于旁路延迟延迟,因此使用FP混合对于掩码 - >结果链只有1个额外的延迟周期,而数据 - >结果链则需要2个额外的周期。


例如,当整数位模式恰好代表了浮点NAN会发生什么?

BLENDVPS并不关心。英特尔的insn ref manual fully documents everything an instruction can/can't doSIMD浮点异常:无意味着这不是问题。另请参阅标记wiki以获取文档链接。

FP blend/shuffle/bitwise-boolean/load/store指令并不关心NaNs。只有执行实际FP数学运算的指令(包括CMPPS,MINPS和类似的东西)才会引发FP异常,或者可能会因非规范化而减慢速度。


我是正确,有一个8位,32位和64位blendv但16位blendv缺少?

是的。但是有32位和16位算术移位,所以使用8位粒度混合至多需要一个额外的指令。 (没有PSRAQ,所以64位整数的blendv通常最好使用BLENDVPD来完成,除非屏蔽生成关闭关键路径和/或相同掩码将在关键路径上多次重复使用。)

最常见的用例是比较掩码,其中每个元素都是全1或全零,因此可以混合使用PAND/PANDN => POR。当然,巧妙的技巧,只留下面具的符号位与真值,可以节省指令和延迟,特别是因为变量混合比三个布尔按位指令稍快。 (例如ORPS两个浮点向量来查看它们是否都是非负的,而不是2个CMPPS和ORing掩码。如果不关心负零,这可以很好地工作)。

+0

感谢您的回答。这是很多的信息。 :)一个简单的问题:你写道:“请注意,自从Sandybridge之后,FP洗牌没有额外的延迟”我理解你是否正确,如果我只针对Sandy Bridge并且更新,那么我可以在__m256i,__m256之间随意投射,和__m256d,除非我使用将位模式解释为浮点的操作,否则不会受到任何处罚? –

+0

@ B.S .:不,我的意思就是我说的。 FP洗牌具有该属性,但FP混合不具备。物理上可能只有一个shuffle执行单元,它连接了FP和ivec转发网络。但混合是便宜(晶体管明智的),我想有单独的混合单位只附加到其中一个转发网络。 –

相关问题