Устранение проверки массивов в CLR? - PullRequest
5 голосов
/ 16 февраля 2012

Я недавно читал эту статью Дэйва Детлефса, в которой он представляет несколько случаев, когда CLR выполняет исключение проверки границ массива. Я решил проверить это сам, поэтому сделал следующее:

  • Открыт Visual Studio 2010 Ultimate SP1
  • Создан новый проект C # типа Консольное приложение (по умолчанию предназначен для .NET 4 Client Profile)
  • Добавлен следующий код (все подчиненные методы взяты непосредственно из статьи):

    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

Итак, вот разборка для [i] = 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 / call - проверка границ, фактически принудительное выполнение вызова вызывает исключение IndexOutOfRangeException.

То же самое для всех обращений к массиву, включая избыточный доступ в Test_SimpleRedundant. Так что-то не так с моей методологией тестирования, или CLR фактически не устраняет проверку границ? Надеюсь, я ошибаюсь, и если да, то мне хотелось бы узнать, как я могу получить проверки границ массивов.

1 Ответ

12 голосов
/ 16 февраля 2012

Благодаря комментарию Коди Грей мне удалось ответить на мой собственный вопрос:

По умолчанию оптимизация JIT отключена при отладке. Чтобы это исправить, можно перейти в «Отладка -> Параметры и настройки -> Отладка -> Общие» и снять флажки «Включить только мой код» и «Подавить оптимизацию JIT при загрузке модуля».

Также см. http://msdn.microsoft.com/en-us/library/ms241594.aspx

При включенной оптимизации проверка границ удаляется в соответствии с объявлением.

Я оставлю это здесь для документации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...