Страницы

Поиск по вопросам

Показаны сообщения с ярлыком jit. Показать все сообщения
Показаны сообщения с ярлыком jit. Показать все сообщения

пятница, 10 января 2020 г.

Чем смотреть исполняемый код .net приложения?

#net #декомпиляция #поиск_программ #jit


Хочу полазить по скомпилированному приложению, чтобы увидеть оптимизации, производимые
jit-компилятором.

Какие программы использовать, чтобы получить листинг нативного кода после прохода
jit и их меппинг на инструкции il-кода? В идеале бы ещё меппинг на C#-код.
    


Ответы

Ответ 1



Запустите или присоединитесь к своему приложению отладчиком Visual Studio, установите брекпойнт в интересующем месте, и когда он сработает - выберите пункт меню "Debug/Windows/Disassembly". Опции для показа IL там нет. Можно только установить галочку "Show source code", и тогда будет показан маппинг машинного и исходного кода(на C#, VB.NET, или на другом языке, на котором вы программируете).

суббота, 4 января 2020 г.

Компилятор javac - статический компилятор?

#java #jit #javac


Цитата из книги "Java. Новое поколение разработки":


  "В техническом отношении с точки зрения теории компиляции байт-код —
  это действительно своеобразный промежуточный язык (intermediate
  language), а не настоящий машинный код. Это означает, что процесс
  преобразования исходного кода Java в байт-код не является компиляцией
  в том смысле, в каком она понимается в языках C и С++. В свою очередь,
  javac не назовешь таким же компилятором, как gcc. В сущности, это
  генератор файлов классов для обработки исходного кода Java. Настоящим
  компилятором в экосистеме Java является динамический компилятор
  (JIT)".


Правильно ли я понимаю, что, в то время как JIT - динамический компилятор, javac
- статический компилятор?
    


Ответы

Ответ 1



Javac не является статическим компилятором. Потому, что он генерирует байт код, который уже в процессе выполнения программы будет динамически компилироваться в машинный код, или интерпретироваться. Но в java 9 появится возможность генерировать машинный код до запуска программы.

суббота, 14 декабря 2019 г.

inline термин в контексте C# / JIT компилятора

#c_sharp #методы #компилятор #inline #jit


Добрый день.
Столкнулся с таким вопросом,а именно хочу четко понять определение термина,такого
как inline метод, соответственно в контексте C#(чтобы вопросы такого рода как "заинлайнить
метод" отпали).  

И вторая часть вопроса,почему JIT компилятору предпочтительнее inline методы?
    


Ответы

Ответ 1



В контексте C#, насколько я понимаю, inline-подстановка означает оптимизацию при компиляции, при которой тело вызываемого метода встраивается в вызывающую функцию вместо вызова. На текущий момент такими оптимизациями занимается только JIT-компилятор. В C# вы не можете заставить компилятор заинлайнить функцию, но вы можете попросить его об этом, используя атрибут [MethodImpl(MethodImplOptions.AggressiveInlining)]. Также вы можете попросить компилятор не встраивать функцию, указав атрибут [MethodImpl(MethodImplOptions.NoInlining)]. В отличие от этого в C++ ключевое слово inline означает, что сборщик должен игнорировать факт множественного определения функции в различных модулях компиляции (ослабляя тем самым ODR). По поводу второй части вопроса: инлайнингом в C# занимается JIT-компилятор потому, что он знает точно целевую платформу. Точные критерии решения JIT-компилятора насчёт того, инлайнить ли данную функцию, меняются от версии к версии. Согласно этому сообщению, инлайнингу не подвержены методы, которые: Маркированы атрибутом MethodImplOptions.NoInlining Размер IL-кода которых больше 32 байт (при отсутствии атрибута MethodImplOptions.AggressiveInlining) Виртуальные методы Метод, принимающие тип-значение большого размера как параметр Методы в классах, производных от MarshalByRefObject Методы со сложным потоком управления например, рекурсивные методы и методы с обработкой исключений Методы с экзотическими инструкциями, проверками безопасности и т. п. Вот такой «список предпочтений» JIT-компилятора насчёт инлайн-методов. Этот список, разумеется, не финальный, и будет пересматриваться (в сторону ослабления) в последующих версиях.

вторник, 26 ноября 2019 г.

JIT optimization


Приветствую, уважаемые!

На днях занимался оптимизацией своего кода и пришел к выводу, что оптимизация V
сломала все мои понятия о "правильном" коде. Чисто случайно наткнулся на забавную вещь:

double res = (int)Math.Round(1.4);


.NET 4.5, в релизе, x86, со включенной оптимизацией работает в 1.5 раза быстрее, чем

double res = Math.Round(1.4);


Я сразу полез в дизассемблированный код, и наткнулся на строки, из-за которых и пишу вам:

double res = (int)Math.Round(1.4);
004E2643  sub         esp,0Ch
004E2646  fld         qword ptr ds:[4E2678h]  
004E264C  fistp       dword ptr [ebp-0Ch]  
004E264F  mov         eax,dword ptr [ebp-0Ch]  
004E2652  mov         dword ptr [ebp-0Ch],eax 
004E2655  fild        dword ptr [ebp-0Ch]


Два дня ломаю мозг, не могу понять, что делают в данном случае команды mov? Может у вас есть идеи?

По просьбам, добавлю:

double res = Math.Round(1.4);
00432646  fld         qword ptr ds:[432670h]  
0043264C  frndint

    


Ответы

Ответ 1



про firstp я нашел вот что Различные ошибки в этой команде могут встречаться на процессорах Pentium. В процессоре Pentium III существуют некоторые ситуации, когда команды FST, FSTP, FIST и FISTP с операндом в памяти не генерируют исключения #P несмотря на проблемы с точностью. Обратитесь к технической документации Intel за описанием всех возможных случаев проявления ошибки. Для однозначного устранения всех предпосылок возникновения этой ошибки используется две команды NOP перед критической командой FPU. У вас после fistp через те самые 2 mov которые ничего вроде не делают идет fild Можно ли ее принять за критическую команду FPU? Скорее да чем нет, а может закладка на все случаи жизни. Так что я бы сказал эти 2 mov работают как упомянутые выше 2 NOP. А может даже лучше.

пятница, 14 июня 2019 г.

Как работает JIT-компилятор в .NET Framework?

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


Ответ

Когда среда CLR выполняет IL код, то происходит следующее: при вызове блока IL-кода JIT-компилятор проверяет и преобразует его в машинные команды которые он сохраняет в динамическом блоке памяти. Затем, он возвращается к структуре данных типа и заменяет адрес вызываемого метода адресом этого блока памяти и при следующем запросе повторная компиляция не будет выполнена, а будет использован уже скомпилированный код.
Теперь, непосредственно, ответ на ваш вопрос: нет, весь скомпилированный код хранится в динамической памяти, а это значит, что этот код уничтожается при выходе из приложения.
В тоже время, существует способ предварительной компиляции приложения в образ в машинном коде (Native Image) с помощью Native Image Generator (Ngen.exe)

среда, 27 февраля 2019 г.

Чем смотреть исполняемый код .net приложения?

Хочу полазить по скомпилированному приложению, чтобы увидеть оптимизации, производимые jit-компилятором.
Какие программы использовать, чтобы получить листинг нативного кода после прохода jit и их меппинг на инструкции il-кода? В идеале бы ещё меппинг на C#-код.


Ответ

Запустите или присоединитесь к своему приложению отладчиком Visual Studio, установите брекпойнт в интересующем месте, и когда он сработает - выберите пункт меню "Debug/Windows/Disassembly".
Опции для показа IL там нет. Можно только установить галочку "Show source code", и тогда будет показан маппинг машинного и исходного кода(на C#, VB.NET, или на другом языке, на котором вы программируете).

понедельник, 28 января 2019 г.

Компилятор javac - статический компилятор?

Цитата из книги "Java. Новое поколение разработки":
"В техническом отношении с точки зрения теории компиляции байт-код — это действительно своеобразный промежуточный язык (intermediate language), а не настоящий машинный код. Это означает, что процесс преобразования исходного кода Java в байт-код не является компиляцией в том смысле, в каком она понимается в языках C и С++. В свою очередь, javac не назовешь таким же компилятором, как gcc. В сущности, это генератор файлов классов для обработки исходного кода Java. Настоящим компилятором в экосистеме Java является динамический компилятор (JIT)".
Правильно ли я понимаю, что, в то время как JIT - динамический компилятор, javac - статический компилятор?


Ответ

Javac не является статическим компилятором. Потому, что он генерирует байт код, который уже в процессе выполнения программы будет динамически компилироваться в машинный код, или интерпретироваться
Но в java 9 появится возможность генерировать машинный код до запуска программы.

вторник, 23 октября 2018 г.

inline термин в контексте C# / JIT компилятора

Добрый день. Столкнулся с таким вопросом,а именно хочу четко понять определение термина,такого как inline метод, соответственно в контексте C#(чтобы вопросы такого рода как "заинлайнить метод" отпали).
И вторая часть вопроса,почему JIT компилятору предпочтительнее inline методы?


Ответ

В контексте C#, насколько я понимаю, inline-подстановка означает оптимизацию при компиляции, при которой тело вызываемого метода встраивается в вызывающую функцию вместо вызова. На текущий момент такими оптимизациями занимается только JIT-компилятор.
В C# вы не можете заставить компилятор заинлайнить функцию, но вы можете попросить его об этом, используя атрибут [MethodImpl(MethodImplOptions.AggressiveInlining)]. Также вы можете попросить компилятор не встраивать функцию, указав атрибут [MethodImpl(MethodImplOptions.NoInlining)]

В отличие от этого в C++ ключевое слово inline означает, что сборщик должен игнорировать факт множественного определения функции в различных модулях компиляции (ослабляя тем самым ODR).

По поводу второй части вопроса: инлайнингом в C# занимается JIT-компилятор потому, что он знает точно целевую платформу. Точные критерии решения JIT-компилятора насчёт того, инлайнить ли данную функцию, меняются от версии к версии.
Согласно этому сообщению, инлайнингу не подвержены методы, которые:
Маркированы атрибутом MethodImplOptions.NoInlining Размер IL-кода которых больше 32 байт (при отсутствии атрибута MethodImplOptions.AggressiveInlining) Виртуальные методы Метод, принимающие тип-значение большого размера как параметр Методы в классах, производных от MarshalByRefObject Методы со сложным потоком управления
например, рекурсивные методы и методы с обработкой исключений Методы с экзотическими инструкциями, проверками безопасности и т. п.
Вот такой «список предпочтений» JIT-компилятора насчёт инлайн-методов.
Этот список, разумеется, не финальный, и будет пересматриваться (в сторону ослабления) в последующих версиях.

вторник, 2 октября 2018 г.

JIT optimization

Приветствую, уважаемые!
На днях занимался оптимизацией своего кода и пришел к выводу, что оптимизация VS сломала все мои понятия о "правильном" коде. Чисто случайно наткнулся на забавную вещь:
double res = (int)Math.Round(1.4);
.NET 4.5, в релизе, x86, со включенной оптимизацией работает в 1.5 раза быстрее, чем
double res = Math.Round(1.4);
Я сразу полез в дизассемблированный код, и наткнулся на строки, из-за которых и пишу вам:
double res = (int)Math.Round(1.4); 004E2643 sub esp,0Ch 004E2646 fld qword ptr ds:[4E2678h] 004E264C fistp dword ptr [ebp-0Ch] 004E264F mov eax,dword ptr [ebp-0Ch] 004E2652 mov dword ptr [ebp-0Ch],eax 004E2655 fild dword ptr [ebp-0Ch]
Два дня ломаю мозг, не могу понять, что делают в данном случае команды mov? Может у вас есть идеи?
По просьбам, добавлю:
double res = Math.Round(1.4); 00432646 fld qword ptr ds:[432670h] 0043264C frndint


Ответ

про firstp я нашел вот что
Различные ошибки в этой команде могут встречаться на процессорах Pentium. В процессоре Pentium III существуют некоторые ситуации, когда команды FST, FSTP, FIST и FISTP с операндом в памяти не генерируют исключения #P несмотря на проблемы с точностью. Обратитесь к технической документации Intel за описанием всех возможных случаев проявления ошибки. Для однозначного устранения всех предпосылок возникновения этой ошибки используется две команды NOP перед критической командой FPU.
У вас после fistp через те самые 2 mov которые ничего вроде не делают идет fild. Можно ли ее принять за критическую команду FPU? Скорее да чем нет, а может закладка на все случаи жизни.
Так что я бы сказал эти 2 mov работают как упомянутые выше 2 NOP. А может даже лучше.