【问题标题】:.NET multiplication optimization.NET 乘法优化
【发布时间】:2010-09-14 17:18:53
【问题描述】:

编译器是否优化了任何乘以 1 的乘法?也就是说,考虑:

int a = 1;
int b = 5 * a;

表达式 5 * a 会被优化为 5 吗?如果不是,如果a被定义为:

const int a = 1;

【问题讨论】:

    标签: c# .net optimization compiler-construction multiplication


    【解决方案1】:

    它会在编译时预先计算任何常量表达式,包括字符串连接。如果没有 const,它将被单独放置。

    你的第一个例子编译成这个 IL:

    .maxstack 2
    .locals init ([0] int32, [1] int32)
    
    ldc.i4.1   //load 1
    stloc.0    //store in 1st local variable
    ldc.i4.5   //load 5
    ldloc.0    //load 1st variable
    mul        // 1 * 5
    stloc.1    // store in 2nd local variable 
    

    第二个例子编译成这样:

    .maxstack 1
    .locals init ( [0] int32 )
    
    ldc.i4.5 //load 5 
    stloc.0  //store in local variable
    

    【讨论】:

    • 即使没有 const,一个称职的编译器也会知道 'a' 在分配和使用之间不会改变。
    • 一个称职的编译器可以假设,但它不知道是否出于某种原因将 int 压入堆栈会阻止它加载到局部变量中。
    • 是优化还是不优化?
    • 我在 3.0 编译器中使用了这些切换:/utf8output /debug- /optimize+ /w:4
    • 这太奇怪了,有点蹩脚——过去 20 或 30 年任何体面的编译器都会优化它
    【解决方案2】:

    恒定传播是最常见和最简单的优化之一。

    【讨论】:

      【解决方案3】:

      编译器在这里优化的不是乘以 1 本身,而是在编译时使用已知值的算术运算。所以是的,编译器会优化你的例子中的所有数学,不管有没有const

      编辑:一个胜任的编译器,我应该说。

      【讨论】:

      • 我编译和反汇编它并没有优化掉非常量表达式。
      • JIT 是否有可能在运行时对其进行优化?
      • @Neil Williams:你希望如此,但 JIT 真的不是你可以在编译时弄清楚的地方。
      【解决方案4】:

      查看单声道编译器生成的代码,带有非常量 a 的版本在运行时执行乘法运算。也就是说,乘法没有被优化。如果你做一个 const,那么乘法就会被优化出来。

      Microsoft 编译器可能有更激进的编译器,最好的解决方案是查看编译器生成的代码,看看它在做什么。

      【讨论】:

        猜你喜欢
        • 2015-12-25
        • 2019-05-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-21
        相关资源
        最近更新 更多