C++11 使用AVX intrinsics进行铸造

C++11 使用AVX intrinsics进行铸造,c++11,avx,avx2,C++11,Avx,Avx2,使用AVX2进行铸造有两种方法: __m256i b = ...set register... auto c = (__m256d)b; // version 1 auto d = _mm256_castsi256_pd(b); // version 2 我假设这两个结果应该是相同的。来自英特尔的消息称,版本2的运行时延迟为零。我可以在零延迟假设下使用版本1吗?此外,我可以假设从任何寄存器类型到版本1的转换是零延迟。至少在gcc中,“版本1”正是“版本2”的实现方式: extern __inl

使用AVX2进行铸造有两种方法:

__m256i b = ...set register...
auto c = (__m256d)b; // version 1
auto d = _mm256_castsi256_pd(b); // version 2

我假设这两个结果应该是相同的。来自英特尔的消息称,版本2的运行时延迟为零。我可以在零延迟假设下使用版本1吗?此外,我可以假设从任何寄存器类型到版本1的转换是零延迟。

至少在gcc中,“版本1”正是“版本2”的实现方式:

extern __inline __m256d __attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_castsi256_pd (__m256i __A)
{
  return (__m256d) __A;
}

叮当声本质上是一样的:

我没有寻找其他编译器,但我也不认为那里会发生什么奇迹


尽管如此,为了便于移植和可读性,我还是建议使用
\u mm256\u castsi256\u pd
,或者如果写得太多,请将其封装到您自己的(内联)函数中。如果您需要重构C样式转换,那么在源代码中很难找到它。

如果您对可移植性感兴趣,那么最好使用版本2-最麻烦的编译器是MSVC,我认为它会抱怨版本1。(虽然我已经有一段时间没有解决这个问题了,所以你可能想用你想要支持的任何编译器来检查自己)。谢谢-请记住这一点。此外,我尝试了版本1,在我的实验中似乎确实有一些开销。尽管如此,最好有一个更技术和完整的答案。你做了什么实验来尝试版本1?我认为任何接受它的编译器都会将其视为与版本2类似的重新解释转换,但错过优化总是可能的。更可能的是,尽管你的实验有缺陷。您是否检查了编译器的asm输出?(无论如何,好问题。我认为答案是,为了便于移植,总是建议使用版本2,但没有理由期望任何一个版本都会汇编到任何额外的指令中,以咀嚼位。)这听起来太复杂了。更可能的情况是,通过使用FP Shuffle或integer比较之间的混合,在使用的任何CPU上引入了额外的旁路延迟,反之亦然。(英特尔SnB系列CPU通常不会对混洗进行跨域处罚,但对混合进行处罚。)。或者您使用的不同洗牌以不同的方式优化或具有不同的吞吐量!显然,您测量的差异似乎不是由于强制转换本身造成的,除非编译器错过了强制转换的优化。