AVX equivalent for _mm_movelh_ps
AVX equivalent for _mm_movelh_ps
由于没有AVX版本的_mm_movelh_ps
我通常使用AVX寄存器的_mm256_shuffle_ps(a, b, 0x44)
作为替代品。但是,我记得在其他问题中读到,如果可能的话,应该首选没有控制整数(如_mm256_unpacklo_ps
或_mm_movelh_ps
)的摆动指令(出于某种原因我不知道)。昨天,我突然想到,另一种选择可能是使用以下方法:
_mm256_castpd_ps(_mm256_unpacklo_pd(_mm256_castps_pd(a), _mm256_castps_pd(b)));
既然强制转换应该是无操作的,这是否比在性能方面使用_mm256_shuffle_ps
更好\等于\更差?
此外,如果真的是这样,如果有人能用简单的话解释(我对汇编和微架构的理解非常有限)为什么人们应该更喜欢没有控制整数的指令,那就太好了。
提前致谢
附加说明:Clang 实际上优化了洗牌以vunpcklpd
:https://godbolt.org/z/9XFP8D 所以看来我的想法还不错。但是,GCC 和 ICC 会创建随机指令。
避免立即节省 1 字节的机器代码大小;仅此而已。 出于性能考虑,它位于列表的底部,但由于这个原因,所有其他相同的洗牌(如具有隐式"控制"的_mm256_unpacklo_pd
)都比直接控制字节略好。
(但是在另一个向量中获取控制操作数(如vpermilps
可以或vpermd
要求)通常更糟,除非你在长时间运行的循环中有一些奇怪的前端瓶颈,并且可以在循环之外加载随机控件。 不是很合理,在这一点上,您必须在 asm 中手动编写才能非常关心代码大小/对齐方式;在C++,这仍然不是你可以直接控制的东西。
既然强制转换应该是无操作的,这是否比在性能方面使用
_mm256_shuffle_ps
更好\等于\更差?
Ice Lake有2个/时钟vshufps
与1个/时钟vunpcklpd
,根据 uops.info 在实际硬件上的测试,在端口1或端口5上运行。一定要用_mm256_shuffle_ps
. 微不足道的额外代码大小成本在早期的CPU上可能根本不会受到伤害,并且对于ICL的未来利益来说可能是值得的,除非您确定端口5不会成为瓶颈。
Ice Lake在端口1上有一个第二个随机单元,可以处理一些常见的XMM和通道内YMM随机播放,包括vpshufb
和显然一些2输入随机播放,如vshufps
。 我不知道为什么它不只是vunpcklpd
解码为具有该控制向量的vshufps
,或者设法在端口 1 上运行该随机播放。 我们知道随机播放硬件本身可以进行随机播放,所以我想这只是控制硬件设置隐式随机播放的问题,以某种方式将操作码映射到随机播放控件。
除此之外,它在较旧的AVX CPU上相同或更好;没有CPU会在其他PS指令之间使用PD洗牌而受到惩罚。 任何现有 CPU 上的唯一区别是代码大小。 像K8和Core 2这样的旧CPU的pd
洗牌速度比ps
快,但是没有AVX的CPU有这个弱点的洗牌单元。 此外,AVX 非破坏性指令在哪个操作数必须作为目标之间存在电平差异。
正如你从Godbolt链接中看到的,在洗牌之前/之后没有额外的指令。 "cast"内部函数不是在进行转换,只是重新解释以保持C++类型系统满意,因为英特尔决定为__m256
与__m256d
(与__m256i
),而不是具有一个通用的 YMM 类型。 他们选择不单独uint8x16
与 不过,uint32x4
ARM 的方式向量;对于整数 SIMD 只需__m256i
.
因此,编译器没有必要为强制转换发出额外的指令,在实践中确实如此;他们不会引入额外的vmovaps
/apd
寄存器副本或类似的东西。
你可以方便地编写它,让clang的shuffle优化器为你发出vunpcklpd
。 或者在其他情况下,无论如何都要做任何它要做的事情;有时它会做出比来源更糟糕的选择,但通常它做得很好。
Clang在-march=icelake-client
上犯了这个错误,即使你写_mm256_shuffle_ps
,仍然使用vunpcklpd
。 (或者根据周围的代码,可能会将该随机播放优化为其他内容的一部分。
相关错误报告。
- 如何将 4 个浮点数的 ps 向量转换为 4 个双精度并存储到 pd 数组
- 旧样式演员的命名演员是什么:pv =(void*)ps;
- popen( "ps -fu $USER" , "r" ) 不会给出所有原始输出结果限制为 81 个字符长
- 在 Linux 上的 C 语言中,popen / system to "ps all > file" 将所有行截断为 80 个字符
- 我的$Foo ATL解决方案中的($Foo)PS项目用于什么
- 如何在 Linux 中检查正在运行的进程版本读取"ps aux"输出
- 在ID3DBlob中初始化PS的DirectX11 CreatePixelShader中发生访问冲突
- 需要C++执行"ps -ef | grep amq | awk '{print $(NF-1)}' "命令
- 对lsof和ps中的列进行对齐
- 常用符号'pS'不是'匹配'使用std::wregex
- 如何在 visual c++ 中以 ns、ps 或 clk 周期为单位测量执行时间