7

「マネージ オーバーヘッド」構造 (チェック インデックス付きの配列など) が使用されていない場合でも、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# のジッターでは、ビルド時の VC よりも実行時にコードをコンパイルする時間がはるかに短いことを理解しています。しかし、たとえば Java のジッタは、頻繁に使用されるメソッドを動的に最適化しています。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# ジッターを改善する計画はありますか?

先月、Microsoft と Xamarin の間で秘密の会議が実際にあったかどうかお尋ねですか? Xamarin がジッターを改善する提出されたパッチを拒否する間、MS は全員を再割り当てしますか?

これはありそうもないことであり、世界中で活発に開発されている他のすべてのソフトウェア プロジェクトと同様に、それを改善する計画があると言えます。

さらに、あなたが提供したコードをできるだけ早く実行したい場合は、手動で最適化しreturn 161315136;ます。このようなコードは、特定のケースで実装 A が実装 B よりも遅いことを証明できますが、いずれかの実装の背後にいる人々がどこに努力を集中すべきかについては何も述べていません。

于 2012-08-16T15:30:44.103 に答える