我试图了解 Roslyn
如何优化以下代码段:
代码
public int F(int n) {
++n;
++n;
++n;
++n;
return n;
}
汇编
C.F(Int32)
L0000: inc edx
L0002: inc edx
L0004: inc edx
L0006: inc edx
L0008: mov eax, edx
L000a: ret
问题
为什么 Roslyn 不像像 MSVC 这样的提前 C 编译器那样对其进行优化? 4 x INC
较慢(4 个周期延迟与 1 个周期延迟相比,即使假设移动消除,比吞吐量所需的多 4 个微指令;https://agner.org/optimize/)。
C
它的“等价物”:
int
f(void *dummy_this, int n) {
++n;
++n;
++n;
++n;
return n;
}
asm 来自 MSVC,或带有 __attribute__((ms_abi))
的 GCC,以使用与 C# asm 相同的 Windows x64 调用约定:https://godbolt.org/z/sK6h7KKcn
f:
lea eax, [rdx+4]
ret
最佳答案
编译器确实进行了优化。 n
是一个参数,所以不能修改。 JIT 编译器必须修改参数值的副本。
如果在递增之前将值分配给变量,Roslyn 编译器将消除递增。来自 this Sharplab.io snippet ,此 C# 代码:
public int F(int i) {
var n=i;
++n;
++n;
++n;
++n;
return n;
}
将被翻译成
public int F(int i)
{
return i + 1 + 1 + 1 + 1;
}
并最终编译成这段汇编代码:
C.F(Int32)
L0000: lea eax, [edx+4]
L0003: ret
关于c# - Roslyn 不优化多个增量是否有原因?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66766573/