【发布时间】:2016-07-25 15:01:12
【问题描述】:
我正在研究 .NET Native 编译器执行的优化技术。 我创建了一个示例循环:
for (int i = 0; i < 100; i++)
{
Function();
}
我已经用 Native 编译了它。然后我在IDA中用机器码反汇编了结果.dll文件。结果,我有:
(我已经删除了一些不必要的行,所以不用担心地址行不一致)
我知道add esi, 0FFFFFFFFh 的真正含义是subtract one from esi and alter Zero Flag if needed,所以如果还没有达到零,我们可以跳到开头。
我不明白的是为什么编译器要反转循环?
我的结论是
LOOP:
add esi, 0FFFFFFFFh
jnz LOOP
只是比例如更快
LOOP:
inc esi
cmp esi, 064h
jl LOOP
但真的是因为这个,速度差异真的很大吗?
【问题讨论】:
-
带有立即值的 ADD 比 INC 更快,并且您还可以跳过 CMP ......所有这些都在 3 行代码中。那么是的,差异非常显着(无论是在大小上还是在速度上)。想象一下,在一个真实世界的程序中,在大约 30000 个地方执行此操作......
-
是的,它更快,而且通常优化器会应用任何可以使您的代码更快而不改变程序语义的优化。
-
是的,因为您甚至不需要比较。你可以(不)看到:)
-
您已经以两种方式编写了代码。如果您想知道一种方式是否比另一种更快,请运行它们。
-
@EricLippert 我并不懒惰,我很愿意,但我现在在我的工作电脑上,我没有任何工具可以运行或对汇编代码进行基准测试 :( 我也没有'没有安装任何东西的管理员权限。
标签: c# assembly x86 micro-optimization .net-native