3.3. Оптимизирующие компиляторы

Эффективность важна на двух стадиях разработки программы: компилирования и выполнения. Если компилятор работает быстро, то он обычно составляет программу, которая выполняется медленно. Компиляторы, создающие эффективную объектную программу, обычно бывают большими и работают медленно, так как оптимизируют объектную программу.

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

WATFIV — быстро работающий компилятор для языка ФОРТРАН, который располагает хорошими средствами отладки, но создает относительно медленную объектную программу.

WATBOL — быстро работающий отладочный-компилятор для программ, написанных на КОБОЛе. Оба компилятора имеются в университете г. Ватерлоо (Канада, Онтарио, Ватерлоо, N2L 3G1).

ALGOL W—быстро работающий компилятор для языка АЛГОЛ, которым располагает Стэнфордский университет. Существует несколько компиляторов для языка ПЛ/1. ПЛ/С — быстро работающий отладочный компилятор, имеющийся в Корнеллском университете, ПЛ/1-оптимизатор — оптимизирующий компилятор вычислительных систем фирмы IBM. Оптимизаторы для языка КОБОЛ обсуждаются в книге М. Стэнли и др.1)

Однако многие машины имеют только один компилятор для каждого языка. В этом случае правильный выбор режима работы компилятора может сократить как время компилирования, так и время выполнения программ. На стадии отладки обычно не используют листинг ассемблера и выходные колоды объектных программ, поэтому они не должны выдаваться по умолчанию. Кроме того, такая информация, как дампы, планы распределения памяти, списки перекрестных ссылок, также не используется, если программист не знает, как ее употребить, или к ней . обращаются очень редко. Тщательное изучение режимов работы компилятора и соответствующее их использование значительно сэкономят время. Можно ввести две процедуры для вызова одного и того же компилятора: первая из них будет вызывать рабочую версию, которая работает быстро и имеет мало дополнительных режимов; вторая предназначена для вызова отладочной версии, предоставляющей много дополнительных возможностей, например печать плана распределения памяти и списка перекрестных ссылок.

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

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

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

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

В последние годы наблюдается феноменальный рост использования мини-ЭВМ; поэтому весьма актуален вопрос о создании эффективных программ, нужных большинству пользователей таких машин. Компиляторы малых машин хуже выполняют оптимизацию объектной программы, чем компиляторы больших машин. Оптимизация больше всего нужна там, где ее почти нет. Если для большой машины есть хороший оптимизирующий компилятор, то целесообразно с помощью этого компилятора получать рабочие программы для малой машины. Эффективное компилирование означает, что большую часть задач можно решить, не прибегая к помощи машинного языка или не переходя на более мощную машину. И то и другое неприемлемо в большинстве случаев.

Можно многое сказать о том, как добиться эффективного выполнения программ. Оставшаяся часть главы посвящена методам создания эффективных программ.

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

Некоторые компиляторы оптимизируют выполнение программы. Имеются два типа такой оптимизации: машинно-зависимая и машинно-независимая. К первому типу относятся способы, результат применения которых зависит от используемой машины. Как правило, эти способы оптимизации обычно не известны или не понятны программистам на уровне входного языка. Они состоят из способов обработки индексов, назначения регистров и анализа машинных команд. - - ^

Второй тип оптимизации — машинно-независимая оптимизация,— которая выполняется на уровне входного языка. Хотя компилятор может оптимизировать программу, но обычно у программиста большие возможности для этого. Многие способы оптимизации может сделать только программист, так как они требуют знания логики программы. Некоторые способы оптимизации, "выполняемые компилятором, могли бы быть применены, но не реализуются просто потому, что требуют слишком много машинного времени. Таким образом, программисты, создающие программы, могут сделать очень много для оптимизации своих программ.

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

Используйте оптимизирующий компилятор.

3.2. Эффективность или удобочитаемость? || Оглавление || 3.4. Оптимизация программ


велюровые костюмы и классные халаты оптом в России

Услуги