Разъяснения по компилятору и интерпретатору JIT

1

У меня есть некоторые сомнения относительно JIT-компилятора и интерпретатора. Начиная с их определений:

(Переводчик) Материал из Википедии:

В информатике интерпретатор представляет собой компьютерную программу, которая непосредственно выполняет, т.е. Выполняет, инструкции, написанные на языке программирования или сценариев, без предварительного пакетного компиляции их на машинный язык. Обычно интерпретатор использует одну из следующих стратегий для выполнения программы:
1) проанализировать исходный код и выполнить его поведение напрямую
2) перевести исходный код в некоторое эффективное промежуточное представление и немедленно выполнить это
3) явно выполнить сохраненный предварительно скомпилированный код [1], сделанный компилятором, который является частью системы интерпретатора

(JIT COMPILER) Материал из Википедии:

При вычислении компиляция "точно в срок" (JIT), также известная как динамический перевод, является компиляцией, выполняемой во время выполнения программы - во время выполнения, а не до ее выполнения. [1] Чаще всего это состоит из перевода в машинный код, который затем выполняется непосредственно, но может также ссылаться на перевод в другой формат.

и From StackOverFlow:

Компиляция "точно вовремя" - это преобразование неродного кода, например байт-кода, в собственный код непосредственно перед его выполнением.

У меня 4 вопроса:
1) Он всегда говорил JIT = время выполнения, почему не работает Interpreter во время выполнения? Не интерпретирует ли переводчик и выполняет каждую строку во время выполнения, пока программа работает?
2) Он всегда говорил, что JIT переводит неродный код в native-код, так что? Разве интерпретатор не конвертирует код в собственный код? Как мой процесс может выполнить инструкцию, если он не переведен на собственный код? Поэтому интерпретатору необходимо также перевести код на собственный код.
3) Нормальный интерпретатор переводит каждую строку, когда ему нужно ее выполнить, при использовании JIT-компилятора каждая строка переводится непосредственно перед ее исполнением, поэтому она доступна в тот момент, когда строка должна быть выполнена. Не так ли?
4) Итак, каков реальный различие между интерпретатором и JIT-компилятором, оба выполняют программу во время выполнения, оба переводятся с промежуточного языка на собственный код...

Теги:
interpreter
jit

3 ответа

4
Лучший ответ

Интерпретатор не переводит исходный код на собственный машинный код. Хотя ваш компьютер способен выполнять машинный код, машинный код, который он выполняет, необязательно должен быть переводом языка более высокого уровня. Смешение? Давайте посмотрим на простой пример игрушек...

Рассмотрим язык программирования PrintForPony, который имеет две функции: print и sleep. Функция print принимает строку символов в качестве единственного аргумента и выводит ее на стандартный вывод, в то время как sleep принимает положительное целое число в качестве единственного аргумента и помещает текущий поток в сон за это время. Псевдо-BNF для PFP:

program        ::= statement_list
statement_list ::= statement | statement NEWLINE statement_list
statement      ::= print STRING | sleep POSITIVE_INTEGER

Вот суперпростая Java-реализация инсепстера для PFP. Программа принимает исходный файл в качестве единственного аргумента и интерпретирует его:

import java.io.BufferedReader;
import java.io.FileReader;

public class PFPInterpreter {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new FileReader(args[0]));
        String line = null;
        while ((line = br.readLine()) != null) {
            if (line.startsWith("print ")) {
                System.out.println(line.substring("print ".length()));
            } else if (line.startsWith("sleep ")) {
                Thread.sleep(Long.parseLong(line.substring("sleep ".length())));
            } else {
                throw new IllegalArgumentException("Unknown function: " + line);
            }
        }
    }
}

Пример исходного файла:

print Hello, World!
sleep 1000
print Goodbye, World!

И выбор образца:

$ java PFPInterpreter test.pfp 
Hello, World!
Goodbye, World!

В какой-то момент PFP не переводится в собственный машинный код. Собственный машинный код, который выполняется, - это JVM, который не имеет ничего общего с этим языком игрушек. Мы могли бы также написать компилятор для PFP, который преобразует код в исполняемый файл (я не собираюсь, потому что этот ответ уже слишком длинный), но дело в том, что интерпретатор не компилируется в native машинный код - он считывает входной файл и делает что-то на основе содержимого.

Чтобы ответить на вопросы:

1) Интерпретатор - это среда выполнения, которая запускает ваш код для вас. Я не уверен, где именно вы читали, что интерпретаторы не работают во время выполнения, но я также не уверен, что это означает.

2) Как показано выше, нет, интерпретатор не переводит на собственный машинный код. JIT-компилятор делает. Ваш процессор выполняет только собственный машинный код, но этот собственный машинный код может быть программой, которая читает произвольный файл и делает что-то на основе содержимого. В этом смысле интерпретатор - это действительно типичная программа, которая принимает входные данные в виде текстовых файлов.

3) JIT-компиляция довольно сложная, и я не эксперт вообще. Однако, например, с помощью Java HotSpot, блоки кода должны выполняться определенное количество раз (1500 для клиента, 15 000 для сервера, IIRC), прежде чем JIT-компилятор будет задействован на них. Вероятно, это связано с тем, что фактическая компиляция не является бесплатной, и очень вероятно, что скомпилированный собственный машинный код кэшируется для последующих исполнений (что объясняет необходимость многих исполнений). Это делает JIT-компиляцию инвестицией (во времени и пространстве), которая может быть не быстрее (возможно, даже медленнее) при первом выполнении, но последующие исполнения будут быстрее, потому что компиляция больше не нужна, а собственный машинный код более эффективен,

4) См. Выше.

Надеюсь, это поможет!

1

1) Он всегда говорил JIT = время выполнения, почему не работает Interpreter во время выполнения? Не интерпретирует ли переводчик и выполняет каждую строку во время выполнения, пока программа работает?

Ты прав; интерпретация обязательно возникает во время выполнения.

2) Он всегда говорил, что JIT переводит неродный код в native-код, так что? Разве интерпретатор не конвертирует код в собственный код? Как мой процесс может выполнить инструкцию, если он не переведен на собственный код? Поэтому интерпретатору необходимо также перевести код на собственный код.

Это правда, что все исполнение в конечном счете является внутренним кодом. Интерпретатор заполняется функциями, которые реализуют эффекты не-родных интерпретируемых инструкций. Эти функции находятся в собственном коде.

3) Нормальный интерпретатор переводит каждую строку, когда ему нужно ее выполнить, при использовании JIT-компилятора каждая строка переводится непосредственно перед ее исполнением, поэтому она доступна в тот момент, когда строка должна быть выполнена. Не так ли?

4) Итак, каков реальный различие между интерпретатором и JIT-компилятором, оба выполняют программу во время выполнения, оба переводятся с промежуточного языка на собственный код...

Разница в том, что JIT может применяться к разделам кода, большим, чем просто один оператор или инструкция. JIT может использоваться для компиляции целых функций, классов или даже всей программы.

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

Вот почему имеет смысл JIT компилировать части кода, которые выполняются повторно. Стоимость компиляции берется только один раз, а выгоды для каждого использования кода.

0

Здесь я сразу отвечу на последний вопрос.

Иногда виртуальная машина Java называется интерпретатором Java; однако, учитывая различные способы выполнения байткодов, этот термин может вводить в заблуждение. Хотя "Java-интерпретатор" является разумным именем для виртуальной машины Java, которая интерпретирует байт-коды, виртуальные машины также используют другие методы (например, компиляцию точно вовремя) для выполнения байт-кодов. Поэтому, хотя все интерпретаторы Java являются виртуальными машинами Java, не все виртуальные машины Java являются Java-переводчиками.

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

  • 0
    «хотя все интерпретаторы Java являются виртуальными машинами Java, не все виртуальные машины Java являются интерпретаторами Java». это довольно запутанно, не могли бы вы объяснить это по-другому?
  • 0
    следуя этой книге "inside-java-virtual-machine", вы получите четкое представление о JVM

Ещё вопросы

Сообщество Overcoder
Наверх
Меню