为什么.Net Native以相反的顺序编译循环?

Kam*_*l T 6 c# x86 assembly micro-optimization .net-native

我正在研究.Net Native编译器执行的优化技术.我创建了一个示例循环:

        for (int i = 0; i < 100; i++)
        {
            Function();
        }
Run Code Online (Sandbox Code Playgroud)

我用Native编译了它.然后我.dll用IDA里面的机器代码反汇编了结果文件.结果,我有:

在此输入图像描述

(我删除了一些不必要的行,所以不要担心地址行不一致)

我明白这add esi, 0FFFFFFFFh意味着subtract one from esi and alter Zero Flag if needed,所以如果还没有达到零,我们可以跳到开头.

我不明白的是为什么编译器重新循环?

我得出结论

LOOP:
add esi, 0FFFFFFFFh
jnz LOOP
Run Code Online (Sandbox Code Playgroud)

比例如更快

LOOP:
inc esi
cmp esi, 064h
jl LOOP
Run Code Online (Sandbox Code Playgroud)

但是真的是因为这个并且速度差异真的很重要吗?

phu*_*clv 5

inc可能比add由于部分标志更新慢。而且add会影响零标志,因此您无需使用其他cmp指令。只是直接跳。

这是一种著名的循环优化类型

反转:循环反转反转了将值分配给索引变量的顺序。这是一个微妙的优化,可以帮助消除依赖性,从而启用其他优化。而且,某些体系结构利用了仅在单个方向上进行计数的汇编语言级别的循环构造(例如,“递减跳跃非零”(DJNZ))。

您可以在此处查看其他编译器的结果