我正在研究由 .NET Native 编译器执行的优化技术。 我创建了一个示例循环:
for (int i = 0; i < 100; i++)
{
Function();
}
我用 Native 编译了它。然后我在 IDA 中反汇编了包含机器代码的结果 .dll
文件。结果,我有:
(我去掉了一些不需要的行,所以不用担心地址行不一致)
我理解 add esi, 0FFFFFFFFh
的意思实际上是从 esi 中减去 1 并在需要时更改零标志
,因此如果没有零,我们可以跳到开头达到了。
我不明白的是编译器为什么要反转循环?
我得出的结论是
LOOP:
add esi, 0FFFFFFFFh
jnz LOOP
只是比例如更快
LOOP:
inc esi
cmp esi, 064h
jl LOOP
但这真的是因为这个吗?速度差异真的很大吗?
最佳答案
inc
might be slower than add
because of the partial flag update .此外,add
会影响零标志,因此您无需使用其他 cmp
指令。直接跳就行了。
这是一个著名的类型 loop optimization
reversal: Loop reversal reverses the order in which values are assigned to the index variable. This is a subtle optimization which can help eliminate dependencies and thus enable other optimizations. Also, certain architectures utilize looping constructs at Assembly language level that count in a single direction only (e.g. decrement-jump-if-not-zero (DJNZ)).
您可以看到其他编译器的结果here .
关于c# - 为什么.NET Native 以相反的顺序编译循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36430287/