Общие оптимизации байт-кода VM на основе стека? - PullRequest
2 голосов
/ 17 января 2020

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


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

Если вы хотите посмотреть на поддерживаемые коды операций, не стесняйтесь проверить их здесь: https://github.com/arturo-lang/arturo/blob/master/src/vm/opcodes.h

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

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

Вот пример (и, будем надеяться, довольно иллюстративный) * Для тех, кто работал с компиляторами, интерпретаторами байт-кода или даже с JVM, приведенный выше код должен быть знаком.


Что я хочу?

Идеи - общие сведения или указать c единиц - о том, как дополнительно оптимизировать мой байт-код.

Например, каждый *2 (то есть: IPUSH2 с последующей инструкцией MUL) преобразуется в: IPUSH1, SHL так как это более быстрая операция.

Что бы вы еще предложили? Есть ли где-нибудь список таких вещей для оптимизации? Не могли бы вы предложить что-то конкретное?

Заранее спасибо! :)

1 Ответ

6 голосов
/ 17 января 2020

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

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

Чтобы иметь возможность оптимизировать этот вид, вы должны попытаться определить так называемые Basi c Блоки (это блоки, в которых выполняются либо все, либо никакие инструкции, т.е. не происходит скачков в блоке или из него), и оптимизируется количество инструкций в этих блоках путем замены нескольких инструкций в одну при сохранении одинаковых семантика кода.

Если вы действительно это имеете в виду, вы также можете попробовать написать бэкэнд ag cc для вашего языка, чтобы скомпилировать его в байт-код; таким образом, вы можете воспользоваться изощренными методами оптимизации g cc в представлении промежуточного кода (RTL).

...