【问题标题】:Performance of assembly function with multiple RET具有多个 RET 的装配功能的性能
【发布时间】:2019-11-26 11:50:38
【问题描述】:

这样的功能对性能有负面影响吗?

fn:
cmp rdi, 0
je lbl0
...
ret
lbl0:
...
ret

call fn

这个呢?

fn0:
... ; no ret, fall through
fn1:
...
ret

【问题讨论】:

    标签: performance assembly x86 x86-64 micro-optimization


    【解决方案1】:

    失败是你能做的最有效的事情;这只是正常的执行。 CPU 甚至不知道“2 个不同的函数”与函数中的标签之间的区别;这一切都只是机器代码。标签是零宽度的,只是为您提供了一种从其他地方引用该地址的方法。

    从高层次来看,您可以将其视为第二个函数的优化尾调用,就像您使用 jmp fn1 而不是 call fn1; ret 所做的那样,然后当然优化掉 jmp +0 因为跳转到下一条指令在架构上是nop


    至于第一个,称为“尾部复制”优化,其中函数的多个路径复制任何必要的清理(pop rbx 或其他)和 ret,而不是运行一个额外的jmp 以达到清理的单个副本。

    尾部复制会占用代码空间(静态代码大小),但会导致每次调用执行的动态指令更少。它通常不会损害分支预测; ret 由一个类似堆栈的预测器预测,它匹配 retcall(即它假设 ret 将返回到最后一个执行的 call。)只要这仍然是真的(它在这里),你没有问题。您有多种方法退出该函数,但每次调用都会运行其中一种方法。

    您还可以进行循环尾复制,在循环内分支,分支的每一侧分别有一个 dec ecx / jnz .top_of_loop(任何必要的 jmp 或循环外的任何内容)。

    【讨论】:

      猜你喜欢
      • 2021-01-29
      • 1970-01-01
      • 2018-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-30
      • 1970-01-01
      • 2019-06-26
      相关资源
      最近更新 更多