有人可以告诉我“即时”的地址模式是否更多 通过[eax]或任何其他方式增加效率。
让我们说我有很长的功能,有些读取和 一些写入(比如5次读取,5次写入)到内存中的某个int值
mov some_addr, 12 //immediate adressing
//other code
mov eax, aome_addr
//other code
mov some_addr, eax // and so on
与
mov eax, some_addr
mov [eax], 12 // addressing thru [eax]
//other code
mov ebx, [eax]
//other code
mov [eax], ebx // and so on
哪一个更快?
答案 0 :(得分:4)
寄存器间接访问可能稍微快一点,但肯定它的编码时间较短,例如(警告 - 气体语法)
67 89 18 mov %ebx, (%eax)
67 8b 18 mov (%eax), %ebx
VS
89 1c 25 00 00 00 00 mov %ebx, some_addr
8b 1c 25 00 00 00 00 mov some_addr, %ebx
所以它在加载instr。,使用缓存等方面有一些影响,因此它可能会快一点,但在 long 函数中 some 读写 - 我认为它不重要......
(十六进制代码中的零应该由链接器填充(只是为了说明这一点)。)
[更新日期=“2012-09-30~21h30 CEST”:
我已经进行了一些测试,我真的很想知道他们透露了什么。我没有进一步调查: - )
48 8D 04 25 00 00 00 00 leaq s_var,%rax
C7 00 CC BA ED FE movl $0xfeedbacc,(%rax)
在大多数运行中都比
更好C7 04 25 00 00 00 00 CC movl $0xfeedbacc,s_var
BA ED FE
我真的很惊讶,现在我想知道Maratyszcza会如何解释这一点。我已经有了一个想法,但我愿意......有趣......不,看到这些(例子)结果
movl to s_var
All 000000000E95F890 244709520
Avg 00000000000000E9 233
Min 00000000000000C8 200
Max 0000000000276B22 2583330
leaq s_var, movl to (reg)
All 000000000BF77C80 200768640
Avg 00000000000000BF 191
Min 00000000000000AA 170
Max 00000000001755C0 1529280
可能肯定会支持他的说法,即指令解码器每个周期最多需要8个字节,但它没有显示真正解码了多少个字节。
在leaq
/ movl
对中,每条指令都是(包括操作数)小于8个字节,因此很可能是每个指令在一个周期内被调度,而单个{ {1}}分为两部分。我仍然相信解码器不会降低速度,因为即使使用11字节movl
,它的工作也是在第三个字节之后完成的 - 那么它只需要等待地址中的流水线流和立即,两者都不需要解码。
由于这是64位模式代码,我还测试了1个字节更短的rip相对寻址 - (几乎)相同的结果。
注意:这些测量可能在很大程度上取决于它们运行的(微)架构。上面的值是在Atom N450上运行测试代码(恒定TSC,boot @ 1.6GHz,在测试运行期间固定在1.0GHz),这不太可能代表整个x86(-64)平台。
注意:测量是在运行时进行的,没有进一步的分析,例如发生的任务/上下文切换或其他干预中断!
/更新]
答案 1 :(得分:3)
使用寄存器寻址最快。