c# - Roslyn 不优化多个增量是否有原因?

标签 c# assembly x86-64 compiler-optimization roslyn

我试图了解 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/

相关文章:

c++ - 未定义对 'some_function' 的引用?

linux - 为什么系统调用会破坏 rcx 和 r11?

c# - 使用 Linq 在列表中查找受骗对象

c# - 无法将类转换为 ObservableCollection

c++ - MSVC 如何优化静态变量的使用?

assembly - 如何在 ARM 汇编中屏蔽字节?

c# - 您可以在自定义渲染器中更改 ToolStripMenuItem 的字体吗

c# - 在构建报告中合并 NUnit 和 NAnt 输出

assembly - 延迟 NIOS 2 组装

linux - 从未对齐 RSP 的函数调用时,glibc scanf 出现段错误