私は最近、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の最適化が無効になっている:コーディグレイコメントへ
「デバッグを開始しました」と言えば、Visual Studio環境からデバッガを接続して*アプリケーションを起動したと仮定します。その場合、JITコンパイルがデフォルトではないので、JITコンパイルが有効になっていることを確認する必要があります。 JITコンパイラは、この最適化を実行するものであり、C#コンパイラではありません。 –
境界チェックが無効になっている場合はどうなりますか?これは一般的に、C#のような管理言語を使用するときに期待される機能です。 –
最適化を確実に行う最も簡単な方法は、実際にデバッグを行わずにアプリケーションを起動し、デバッガを接続することです。 – svick