7

我注意到 C# jitter 产生的代码比 C++ 编译器慢得多,即使没有使用“托管开销”结构(例如带有检查索引的数组)。

为了量化它,我对以下简单循环进行了计时:

public static int count = 1000000000;
public static int Main()
{
    int j = 0;
    for (int i = 0; i < count; ++i)
    {
        j += (i % 2 == 0) ? ((i + 7) >> 3) : (i * 7);
    }
    return j;
}

这个循环需要 3.88 秒来执行(用 /o 编译)。使用 VC 2010 (-O2) 编译的等效循环需要 2.95 秒。

为了验证是否确实生成了劣质代码,我比较了机器代码:从 VC 编译器创建了一个列表 (/FAs),并将调试器附加到 C# 程序(循环完成后)。

事实上,C++ 版本正在使用一些巧妙的技巧。例如,为了避免代价高昂的乘以 7,有一个单独的寄存器,每次循环计数都会增加 7。C# 版本每次都进行乘法 (imul)。还有其他差异。

我知道 C# jitter 在运行时编译代码的时间比 VC 在构建时要少得多。但例如Java jitter 正在动态优化常用方法。C# 似乎没有这样做。

我的问题是:是否有计划在未来的框架版本中改进 C# 抖动?

4

2 回答 2

9

发布版本,VS2008SP1,.NET 3.5SP1,平均 10 次测试:

.NET, x86:   2.646 seconds
C++, x86:    2.652 seconds
.NET, x64:   2.352 seconds
C++, x64:    2.090 seconds

经典错误假设 /o 很重要,测量抖动时间,运行调试构建,使用附加的调试器进行测试,因此禁用了抖动优化器。

x64 抖动使用您提到的相同技巧,它不是 C++ 代码生成器所独有的:

00000030  xor         r9d,r9d 
... 
00000059  add         r9d,7

.NET 4.5 的一项新功能是配置文件引导优化。

像微软这样的公司永远不会分享未来的计划,猜测它们是没有意义的。

于 2012-08-16T18:34:08.617 回答
3

是否有计划在未来的框架版本中改进 C# 抖动?

你是在问微软和 Xamarin 上个月是否真的举行过一次秘密会议,他们一致认为,虽然他们在过去十年里都在改善各自的不安,但从现在开始,他们厌倦了让事情变得更好,并且会不再打扰,MS 会重新分配每个人,而 Xamarin 会拒绝任何提交的改善抖动的补丁?

我会说这不太可能,就像世界上其他所有积极开发的软件项目一样,也有改进它的计划。

此外,如果我真的想尽快运行您提供的代码,我会将其手动优化为return 161315136;. 这样的代码可以证明在特定情况下实现 A 比实现 B 慢,但没有说明任何实现背后的人应该集中精力在哪里。

于 2012-08-16T15:30:44.103 回答