C# 将c代码分解为机器指令

C# 将c代码分解为机器指令,c#,performance,x86,cil,ildasm,C#,Performance,X86,Cil,Ildasm,我正在试验编译器的性能。我有一段非常小的代码,只有一些浮点乘法和加法。代码在循环中执行数百万次。我正在尝试编译C++、C语言、java、perl、python……的代码…然后我在测量执行时间的同时运行结果 我对c#的表现很不满意。我的C代码比等效的C++或java慢60%左右。我肯定,我的实验中一定有一个错误。我想分解生成的二进制文件来了解原因 MSIL代码有这样的选项吗?c#JIT编译器的结果是否可以在机器指令级别(x86指令,而不是MSIL指令)进行检查 更新 代码(u、v、g*为双精度;步

我正在试验编译器的性能。我有一段非常小的代码,只有一些浮点乘法和加法。代码在循环中执行数百万次。我正在尝试编译C++、C语言、java、perl、python……的代码…然后我在测量执行时间的同时运行结果

我对c#的表现很不满意。我的C代码比等效的C++或java慢60%左右。我肯定,我的实验中一定有一个错误。我想分解生成的二进制文件来了解原因

MSIL代码有这样的选项吗?c#JIT编译器的结果是否可以在机器指令级别(x86指令,而不是MSIL指令)进行检查

更新

代码(u、v、g*为双精度;步长为整数)

stopwatch.Start();
对于(int i=0;i
也许您可以先(编译为本机代码)二进制文件,以避免JIT编译。

您的程序并反汇编结果。

在Visual Studio中调试代码(但在发布模式下编译),在循环中放置断点,然后打开反汇编窗口(调试->窗口->反汇编)当执行在断点处停止时。

您确定您的基准测试首先允许JIT启动吗?也许你应该展示一下。@delnan:你是什么意思?如果JIT没有编译代码,代码就无法运行。@Guffa:问题是JIT时间是否应该包含在基准测试中。向我们展示代码并描述您如何运行它的场景。指定测量时间的方式和地点。请注意这样一个事实,您的代码和它的任何日历在第一次被调用时都会出现抖动,这当然会带来时间惩罚。在这之后,没有太多的理由说明代码的运行速度应该比直接编译成本机二进制的等效代码慢。是的,正是@Guffa的意思,他只是比我快(而且不那么冗长)。@Guffa,Paul Michalik-执行时间在3到5秒之间。@danatel:这很有效,但你可能需要做得更好。重写程序以运行感兴趣的代码两次,并在两次运行之间显示一个消息框。当消息框出现时,将调试器附加到进程。记住,抖动知道您是否正在调试。当调试器运行时,它可以并且确实会生成优化程度较低的代码,以改善调试体验。如果您想知道调试程序未运行时抖动在做什么,请在抖动第一次生成代码后附加调试程序。@Eric Lippert:我知道在“调试更多”模式下编译与在“发布”模式下编译有很大区别,但这是否也取决于是否附加了调试器?Guffa:可能有。jitter知道是否连接了调试器,并且可以选择跳过一些使调试变得困难的优化。@Eric Lippert:谢谢你的建议,但是在这种情况下,即使在调试模式下,差异也很明显。C++代码巧妙地将所有东西都放在FPU栈中,C是从RAM中推拉变量的。我实验的下一步是使用gcc和intel编译器进行比较。@debug builds中的danatel(技术上是指任何不具有允许优化属性的程序集)在JIT时停止注册变量,因此任何以这种方式查看调试版本的做法都是愚蠢的,除非您感染了正常运行的调试版本!
stopwatch.Start();
for (int i = 0; i < steps; i++)
{
    double uu = g11 * u + g12 * v;
    v = g21 * u + g22 * v;
    u = uu;
}
stopwatch.Stop();