【发布时间】:2022-12-05 04:48:01
【问题描述】:
据我所知,SSE/AVX 中没有加载立即数的指令。一种解决方法是将值加载到普通寄存器和 movd,但编译器似乎认为这比从内存加载更昂贵,即使对于单个标量值也是如此。
这使得每次使用1、0x80000000、0x7fffffff、0x3f800000、0x3f000000等公共常量进行操作时都需要内存访问。好吧,将这些值编码在机器代码中将占用 4每个字节,但 32 位绝对地址或 rip- 相对地址也是如此,我相信立即加载比任何类型的内存加载都便宜。
我一直认为 movss xmm, imm32 或 broadcastss xmm, imm32 之类的东西会很好,但一定有不做这样的指示的原因。为什么要这样设计?
【问题讨论】:
-
相比之下,ARM NEON 确实有将立即值广播到向量中的指令。如果它们同样适用于 NEON,则作为答案发布的原因将不会令人信服。
-
除非 SSE/AVX 设计团队的某个人看到这个问题并愿意讨论他们的想法,否则这可能无法回答。
-
对此的标准解决方案是从内存中加载一个常量。这就是指令集的设计方式,在 MMX 和 x87 浮点单元上也是如此。
-
这些常量中的几个(其中所有设置位在寄存器的一端都是连续的)可以在 2 条指令中生成,从
pcmped xmm0,xmm0(全一)开始。请参阅What are the best instruction sequences to generate vector constants on the fly? 和 Agner Fog 的指南。但是 2 条指令仍然比 1 条或内存源操作数差,因此编译器通常不会这样做。 -
@PeterCordes:但即使是一个字节的立即数也可能非常有用。 NEON move-immediate 只包含一个 8 位立即数(有几个不同的解码选项),这可能涵盖了 95% 的用例。
标签: assembly x86 sse instruction-set immediate-operand