Не переводчики JIT и не с поддержкой JIT в конечном итоге создают машинный код - PullRequest
7 голосов
/ 23 января 2012

Хорошо, я прочитал несколько дискуссий, касающихся различий между JIT и не-JIT-интерпретаторами, и почему JIT обычно повышает производительность.

Однако мой вопрос:

В конечном счете, неНе должен ли интерпретатор, не поддерживающий JIT, превращать байт-код (строка за строкой) в машинный / нативный код для выполнения, как это сделает компилятор JIT?Я видел посты и учебники, которые говорят, что это так, и посты, которые говорят, что это не так.Последний аргумент заключается в том, что интерпретатор / JVM выполняет этот байт-код напрямую, без взаимодействия с машинным / собственным кодом.

Если интерпретаторы, не являющиеся JIT, превращают каждую строку в машинный код, кажется, что основными преимуществами JIT являются:...

  1. Интеллектуальное кэширование всех (обычный JIT) или часто встречающихся (горячая точка / адаптивная оптимизация) частей байт-кода, так что этап компиляции машинного кода не требуется каждый раз.

  2. Любая оптимизация JIT-компиляторов может быть выполнена при преобразовании байт-кода в машинный код.

Это точно?Кажется, между переводом байт-кода в машинный код через интерпретаторы, не поддерживающие JIT и JIT, существует небольшая разница (кроме возможной оптимизации или блоков JITting против строк за строкой).

Заранее спасибо.

Ответы [ 2 ]

9 голосов
/ 23 января 2012

Интерпретатор не-JIT не преобразует байт-код в машинный код.Вы можете представить себе работу интерпретатора байт-кода не-JIT примерно так (я буду использовать псевдокод, подобный Java):

int[] bytecodes = { ... };
int   ip        = 0; // instruction pointer
while(true) {
  int code = bytecodes[ip];
  switch(code) {
    case 0;
      // do something
      ip += 1; break;
    case 1:
      // do something else
      ip += 1; break;
    // and so on...
  }
}

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

С JIT все эти издержки будут сведены к нулю.Он просто взял бы содержимое соответствующих ветвей переключателя (части, которые говорят «// сделать что-то»), связал их вместе в памяти и выполнил бы переход к началу первой.Никакой программный «указатель инструкций» не требуется - только указатель аппаратного обеспечения процессора.Нет необходимости извлекать байт-коды из памяти и включать их значения.

Запись виртуальной машины не сложна (если она не должна быть очень высокой производительности) и может быть интересным упражнением.Я сделал один раз для встроенного проекта, где программный код должен был быть очень компактным.

0 голосов
/ 19 февраля 2013

Несколько десятилетий назад, казалось, широко распространено мнение, что компиляторы превратят всю программу в машинный код, в то время как интерпретаторы переводят оператор в машинный код, исполняют его, отбрасывают, переводят следующий и т. Д.99% неверно, но в этом было два крошечных ядра истины.На некоторых микропроцессорах некоторые инструкции требовали использования адресов, указанных в коде.Например, на 8080 была инструкция для чтения или записи указанного адреса ввода / вывода 0x00-0xFF, но не было инструкции для чтения или записи адреса ввода / вывода, указанного в регистре.Для интерпретаторов языка было обычным делом, если пользовательский код делал что-то вроде «out 123,45», чтобы сохранить в три байта памяти инструкции «out 7Bh / ret», загрузить аккумулятор с 2Dh и сделать вызов первого изэти инструкции.В этой ситуации интерпретатор действительно будет генерировать инструкцию машинного кода для выполнения интерпретированной инструкции.Такая генерация кода, однако, в основном ограничивалась такими вещами, как инструкции IN и OUT.

Многие распространенные интерпретаторы Microsoft BASIC для 6502 (и, возможно, также для 8080) сделали несколько более широкое использование кода, хранящегося в ОЗУ,но код, который был сохранен в ОЗУ, не сильно зависит от программы, которая выполнялась;большая часть подпрограммы в ОЗУ не изменилась бы во время выполнения программы, но адрес следующей инструкции оставался встроенным как часть подпрограммы, позволяющей использовать инструкцию "LDA" в абсолютном режиме, что позволило сохранить по крайней мере один циклкаждая выборка байтов.

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