寻址模式效率

时间:2012-09-26 12:44:23

标签: optimization assembly x86 cpu addressing-mode

有人可以告诉我“即时”的地址模式是否更多 通过[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

哪一个更快?

2 个答案:

答案 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)

使用寄存器寻址最快。

请参阅Register addressing mode vs Direct addressing mode