具有多个 RET 的汇编函数的性能

Performance of assembly function with multiple RET

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

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

call fn

还有这个?

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

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

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


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

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

你也可以做循环尾部复制,你在循环内分支,分支的每一侧分别有一个 dec ecx / jnz .top_of_loop(有任何必要的 jmp 或循环外的任何东西)。