我想看看如何Roslyn
优化以下代码片段:
code
public int F(int n) {
++n;
++n;
++n;
++n;
return n;
}
asm
C.F(Int32)
L0000: inc edx
L0002: inc edx
L0004: inc edx
L0006: inc edx
L0008: mov eax, edx
L000a: ret
Question
为什么 Roslyn 不像 MSVC 这样的提前 C 编译器那样对其进行优化?4 x INC
速度较慢(4 个周期延迟 vs. 1 个周期延迟,即使假设 mov 消除,并且比吞吐量所需的微指令多 4 个;https://agner.org/optimize/ https://agner.org/optimize/).
C
它的“等价物”:
int
f(void *dummy_this, int n) {
++n;
++n;
++n;
++n;
return n;
}
asm来自 MSVC 或 GCC__attribute__((ms_abi))
使用与 C# asm 相同的 Windows x64 调用约定:https://godbolt.org/z/sK6h7KKcn https://godbolt.org/z/sK6h7KKcn
f:
lea eax, [rdx+4]
ret
编译器会进行优化。n
但它是一个参数,因此无法修改。 JIT 编译器必须修改copy参数的值。
如果在递增之前将值分配给变量,Roslyn 编译器将消除增量。从这个 Sharplab.io 片段 https://sharplab.io/#v2:EYLgtghglgdgPgAQEwEYCwAoBBmABM3AYVwG9NcL89YAXXAMQApbcoBKU8y7gNwgCdcMALxQA3F24UA1NJhipFSVNnzFuZd1ULFmytvWY9FBAHYhEjNwC+3TNaA=,这段 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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)