Слово об оптимизации

Слово об оптимизации

Раннее в этой главе я обещал дать несколько подсказок как мы можем повысить качество генерируемого кода. Как я сказал, получение компактного кода не является главной целью этой книги. Но вам нужно по крайней мере знать, что мы не зря проводим свое время… что мы действительно можем модифицировать анализатор для получения лучшего кода не выбрасывая то, что мы уже сделали к настоящему времени. Обычно небольшая оптимизация не слишком трудна… просто в синтаксический анализатор вставляется дополнительный код.

Существуют два основных метода, которые мы можем использовать:

Попытаться исправить код после того, как он сгенерирован.

Это понятие «щелевой» оптимизации. Основная идея в том, что известно какие комбинации инструкций компилятор собирается произвести и также известно которые из них «плохие» (такие как код для числа -1). Итак, все что нужно сделать – просканировать полученный код, найти такие комбинации инструкций и заменить их на более «хорошие». Это вид макрорасширений наоборот и прямой пример метода сопоставления с образцом. Единственная сложность в том, что может существовать множество таких комбинаций. Этот метод называется «щелевой» оптимизацией просто потому, что оптимизатор работает с маленькой группой инструкций. «Щелевая» оптимизация может драматически влиять на качество кода и не требует при этом больших изменений в структуре компилятора. Но все же за это приходится платить скоростью, размером и сложностью компилятора. Поиск всех комбинаций требует проверки множества условий, каждая из которых является источником ошибки. И, естественно, это требует много времени.

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

Попытаться сразу генерировать лучший код.

В этом методе выполняется проверка дополнительных условий перед выводом кода. Как тривиальный пример, мы должны были бы идентифицировать нуль и выдать CLR вместо загрузки, или даже совсем ничего не делать, как в случае с прибавлением нуля, например. Конкретней, если мы решили распознавать унарный минус в процедуре Factor вместо Expression, то мы должны обрабатывать –1 как обычную константу, а не генерировать ее из положительных. Ни одна из этих вещей не является слишком сложной для реализации… просто они требуют включения дополнительных проверок в код, поэтому я не включил их в программу. Как только мы дойдем до получения работающего компилятора, генерирующего полезный выполнимый код, мы всегда сможем вернуться и доработать программу для получения более компактного кода. Именно поэтому в мире существует «Версия 2.0».

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

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

Хорошо, процессор 68000 имеет восемь регистров данных. Почему бы не использовать их как стек? В любой момент своей работы синтаксический анализатор «знает» как много элементов в стеке, поэтому он может правильно ими манипулировать. Мы можем определить частный указатель стека, который следит, на каком уровне мы находимся и адресует соответствующий регистр. Процедура Factor, например, должна загружать данные не в регистр D0, а в тот, который является текущей вершиной стека.

Что мы получаем заменяя стек в RAM на локальный стек созданный из регистров. Для большинства выражений уровень стека никогда не превысит восьми, поэтому мы получаем достаточно хороший код. Конечно, мы должны предусмотреть те случаи, когда уровень стека превысит восемь, но это также не проблема. Мы просто позволим стеку перетекать в стек ЦПУ. Для уровней выше восьми код не хуже, чем тот, который мы генерируем сейчас, а для уровней ниже восьми он значительно лучше.

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

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

В следующей главе я покажу вам как работать с переменными и вызовами функций. Я также покажу вам как легко добавить поддержку многосимвольных токенов и пробелов.

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг:

21.1.8. Опции оптимизации

Из книги автора

21.1.8. Опции оптимизации Компилятор gcc позволяет оптимизировать код вашей программы. Другими словами, gcc сделает все для того, чтобы ваша программа была как можно меньше по размеру и как можно быстрее запускалась. Для включения режима оптимизации используйте опцию -O1. Вы


Последовательность оптимизации

Из книги автора

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


2. Магическое слово «ДЛЯ»

Из книги автора

2. Магическое слово «ДЛЯ» Мы уже говорили, что это слово хорошо работает. Ваш курс может быть для новичков, для продвинутых, для женщин или для тех, кому за 50. То есть для определенной категории людей: сетевиков, инфобизнесменов, просто бизнесменов и людей, которые лишились


5. Магическое слово «БЕЗ»

Из книги автора

5. Магическое слово «БЕЗ» Это еще одно магическое слово для отстройки от конкурирующих инфопредложений. Посмотрите внимательно на своих конкурентов. Предположим, ваша тема – «Как сбросить вес». Ваш конкурент говорит своим клиентам: «Чтобы сбросить вес, надо перестать


Методы оптимизации

Из книги автора

Методы оптимизации Существуют различные методы машинно-зависимой и машинно-независимой оптимизации кода. Они могут применяться на всех синтаксических уровнях. Одним из простейших методов является "размножение констант". При его применении любая ссылка на константное


1.6.15. Правило оптимизации: создайте опытные образцы, заставьте их работать, прежде чем перейти к оптимизации

Из книги автора

1.6.15. Правило оптимизации: создайте опытные образцы, заставьте их работать, прежде чем перейти к оптимизации Самый основной аргумент в пользу создания прототипов впервые был выдвинут Керниганом и Плоджером (Plauger): "90% актуальной и реальной функциональности лучше, чем 100%


12.1. Отказ от оптимизации

Из книги автора

12.1. Отказ от оптимизации Наиболее мощная методика оптимизации, входящая в инструментарий любого программиста, заключается в том, чтобы ничего не делать.Этот весьма выдержанный в духе Дзэн совет верен по нескольким причинам. Одной из них является экспоненциальный эффект


1.6.15. Правило оптимизации: создайте опытные образцы, заставьте их работать, прежде чем перейти к оптимизации

Из книги автора

1.6.15. Правило оптимизации: создайте опытные образцы, заставьте их работать, прежде чем перейти к оптимизации Самый основной аргумент в пользу создания прототипов впервые был выдвинут Керниганом и Плоджером (Plauger): "90% актуальной и реальной функциональности лучше, чем 100%


12.1. Отказ от оптимизации

Из книги автора

12.1. Отказ от оптимизации Наиболее мощная методика оптимизации, входящая в инструментарий любого программиста, заключается в том, чтобы ничего не делать.Этот весьма выдержанный в духе Дзэн совет верен по нескольким причинам. Одной из них является экспоненциальный эффект


Искусство оптимизации

Из книги автора

Искусство оптимизации В этом разделе речь пойдет об оптимизации изображений для Интернета и портативных устройств.Дело в том, что обычное сохранение с помощью команд File ? Save (Файл ? Сохранить) и File ? Save As (Файл ? Сохранить как) не позволяет реализовать все возможности


9.5. Вопросы оптимизации

Из книги автора

9.5. Вопросы оптимизации Даже при наличии в программе ассемблерных вставок модуль оптимизации компилятора пытается переупорядочить и переписать код программы, чтобы минимизировать время ее выполнения. Когда оптимизатор обнаруживает, что выходные данные функции asm() не


Ключевое слово this

Из книги автора

Ключевое слово this Ключевое слово this представляет собой указатель на текущий объект класса. Методы класса могут использовать ключевое слово this чтобы получить указатель на объект для которого вызван данный метод. Указатель this представляет собой постоянную величину, вы не