2012-02-16 25 views
5

私は最近、Dave Detlefsによってthis articleを読んでいました。ここでは、CLRが配列境界チェックを実行するいくつかのケースを示しています。私はこの自分自身をテストすることを決めたので、私は次のようでした(デフォルトでは、.NET 4クライアントプロファイルをターゲット)タイプコンソールアプリケーションの新しいC#プロジェクト CLRの配列境界チェック削除?

  • を作成し

    • オープンのVisual Studio 2010の究極のSP1
    • は、(すべてのサブメソッドを物品から直接取得される)、次のコードを追加:

      class Program { 
          static void Main(string[] args) { 
           int[] array = new int[30]; 
           Test_SimpleAscend(array); 
           Test_SimpleRedundant(array, 3); 
      
           foreach (int i in array) { 
            Console.WriteLine(i); 
           } 
          } 
      
          static void Test_SimpleAscend(int[] a) { 
           for (int i = 0; i < a.Length; i++) 
            a[i] = i; 
          } 
      
          static void Test_SimpleRedundant(int[] a, int i) { 
           int k = a[i]; 
           k = k + a[i]; 
          } 
      } 
      
    • はモードを解除するスイッチ。 「最適化コード」

    • が追加され、各配列のアクセスにブレークポイントは、(F5)をデバッグを開始したビルドオプションにチェックされていることを検証し、

    だからここには用dissassemblyだDissassemblyウィンドウを開いて[I] =私; Test_SimpleAscendに:

       a[i] = i; 
    00000024 mov   eax,dword ptr [ebp-4] 
    00000027 mov   edx,dword ptr [ebp-8] 
    0000002a cmp   eax,dword ptr [edx+4] 
    0000002d jb   00000034 
    0000002f call  64FD6E08 
    00000034 mov   ecx,dword ptr [ebp-4] 
    00000037 mov   dword ptr [edx+eax*4+8],ecx 
    

    CMP/JB /コール実際に実行されるようにIndexOutOfRangeExceptionをスローコールを強制的に、境界チェックです。

    Test_SimpleRedundantの冗長アクセスを含め、すべてのアレイアクセスで同じことです。だから、私のテスト方法論に何か間違っている、またはCLRは実際に境界チェックを排除していないのですか?私が間違っていることを願っています。もしそうなら、どうすれば本当に配列の境界をどのように削除するかを知ることができます。デバッグ時

    は、デフォルトでは、JITの最適化が無効になっている:コーディグレイコメントへ

  • +10

    「デバッグを開始しました」と言えば、Visual Studio環境からデバッガを接続して*アプリケーションを起動したと仮定します。その場合、JITコンパイルがデフォルトではないので、JITコンパイルが有効になっていることを確認する必要があります。 JITコンパイラは、この最適化を実行するものであり、C#コンパイラではありません。 –

    +0

    境界チェックが無効になっている場合はどうなりますか?これは一般的に、C#のような管理言語を使用するときに期待される機能です。 –

    +1

    最適化を確実に行う最も簡単な方法は、実際にデバッグを行わずにアプリケーションを起動し、デバッガを接続することです。 – svick

    答えて

    12

    おかげで、私は自分の質問に答えることができました。これを修正するには、[デバッグ] - > [オプションと設定] - > [デバッグ] - > [一般]を選択し、[コードを有効にする]と[モジュールの負荷でJIT最適化を無効にする]

    も有効に最適化してhttp://msdn.microsoft.com/en-us/library/ms241594.aspx

    を参照宣伝として、境界チェックが削除されます。

    ここでは、ドキュメント化のためにこのままにしておきます。

    関連する問題