【问题标题】:C# jitter improvements in future framework versions未来框架版本中的 C# 抖动改进
【发布时间】:2013-05-02 21:11:38
【问题描述】:

我注意到 C# 抖动产生的代码比 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# 抖动?

【问题讨论】:

  • Visual Studio RC 2012 with .NET 4.5 从昨天开始可供下载。下载它(它是免费的)并在那里运行相同的测试。
  • 很久以前,我已经不再为抖动所做的新优化而屏住呼吸了。 MS 似乎认为它在那个部门已经足够好了。
  • @JonHanna 从 .NET 4 开始。3.5 有一些好东西,没想到太多,但在那之后 NGen 得到了所有的爱。
  • @harold 在 4.0 中完成尾调用消除的更大情况并非仅限 NGen。
  • 您的测试经过精心挑选,以展示 C++ 比 C# 快的一种特定情况。我从未见过这种情况出现在我处理过的代码中,所以对我来说 JIT 用它做什么并不重要。如果您再次运行测试但专注于内存分配器(实际上几乎每个人都在使用它),我想您会发现结果大不相同。

标签: c# optimization jit


【解决方案1】:

发布版本,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 的一项新功能是配置文件引导优化。

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

【讨论】:

    【解决方案2】:

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

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

    我会说这不太可能,并且与世界上所有其他积极开发的软件项目一样,我们有计划对其进行改进。

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

    【讨论】:

    • 这段代码是为了证明 C# 抖动应该归咎于 C# 比 C++ 慢,而不仅仅是很多人(包括 Herb Sutter)提到的“管理开销”。显然,性能不仅仅是简单的整数运算和分支。
    • 是的,但除了@HansPassant 得到的结果之外,还有一个问题是它的相关性。抖动团队是否一定要为此付出努力?如果他们这样做了,他们中的任何一个人写下来会足够有趣吗?我想它会出现在您在有关此类问题的文章中获得的“并且我们做了一些其他改进”行之下,而不是它们是关于循环中的乘法变得更快的一系列博客文章。
    • 我认为通过改进 C# jitter 可以获得显着的收益。我希望在计算机语言基准游戏 (shootout.alioth.debian.org) 中看到 C# 匹配或超越 Java。 C# 具有本机值类型,很遗憾 Java 在大多数情况下都快得多。尽管他们使用 Mono 进行测试,而不是那里的 MS 实现。
    • 我也这么认为。我不明白为什么您怀疑 Microsoft 和 Xamarin 可能不会?
    • .NET 已有 10 多年的历史,经历了多次修改,但自早期以来,jitting 部门并没有太大变化。随意告诉我我错了——但事实仍然是,理论上应该更糟的 Java 仍然遥遥领先。如果 .NET 表现更好,微软可能不会觉得有必要在 Windows 8 上掉头回到 C++。
    猜你喜欢
    • 1970-01-01
    • 2019-03-22
    • 2016-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-03
    相关资源
    最近更新 更多