如何强制编译器使用ldc.i8 IL指令而不是ldc.i4加上conv.i8?

时间:2016-11-14 15:58:58

标签: c# .net cil

这是我的C#代码:

const long pSize = 20;

无论我使用x64还是Any CPU在Release模式下构建它,我都会得到MSIL指令:

  IL_0010:  ldc.i4.s   20
  IL_0012:  conv.i8

但是,MSIL有ldc.i8指令。如何使编译器使用它?

1 个答案:

答案 0 :(得分:25)

  

MSIL有ldc.i8指令。如何使编译器使用它?

你没有。这将是更糟糕的代码。

ldc.i4.s   20
conv.i8

是三个字节的代码:两个用于指令,一个用于常量。而

ldc.i8 20

是九个字节:一个用于指令,八个用于常量。

编译器足够智能,可以避免六个不必要的字节。请记住,代码的速度可能会受到将其加载到内存所需的页面错误数量的不利影响;生成的代码比它需要的大三倍可以实现该目标。

但等等,还有更多,而且一切都很糟糕。

基本代码块越大,它周围的分支越可能比紧凑分支指令格式更合适。这意味着这种去优化可以使分支指令变大,从而使他们的基本块更大,现在可能围绕它们的分支不紧凑,整个事情可以滚雪球。

这不仅仅是额外的六个字节;这是使得其他代码更大的六个额外字节的所有后果;你也必须考虑到这笔费用。

编译器做得很好。让它做它的工作。

如果你的心脏有一个编译器生成更糟糕的代码,编译器的源代码是可用的。如果由于某种原因确实需要编译器,请随意编写去优化编译器。