Многие программисты используют методы, с которыми они познакомились при
изучении компиляторов, не только для написания компиляторов или каких-то их
частей. Эти методы находят широкое применение и в других областях. Проектирование
компиляторов затрагивает ряд других областей информатики, и в этом разделе мы
рассмотрим некоторые наиболее важные взаимодействия и приложения компиляторных
технологий.
Реализация высокоуровневых
языков программирования
Высокоуровневый
язык программирования определяет программную абстракцию: программист выражает
алгоритм с использованием языка, а компилятор должен транслировать эту
программу в целевой язык. Вообще говоря, высокоуровневые языки
программирования проще для программирования, но менее эффективны, т.е. целевые
программы работают более медленно. Программисты, использующие низкоуровневые
языки, обладают большими возможностями контроля над выполняемыми вычислениями
и могут, в принципе, получать более эффективный код. К сожалению, на
низкоуровневых языках труднее писать программы, и, что еще хуже, эти языки
менее переносимы, программы на них более подвержены ошибкам и их труднее
сопровождать. Оптимизирующие компиляторы включают технологии для повышения
производительности генерируемого кода, тем самым компенсируя неэффективность
высокоуровневых абстракций.
Пример 1.2. Ключевое
слово register в языке
программирования С представляет собой пример взаимодействия между методами
компиляции и эволюцией языка.
Когда язык С
создавался в средине 1970-х годов, считалось необходимым позволить
программисту определять, какие переменные должны размещаться в регистрах.
Однако после разработки эффективных методов распределения регистров такое
управление стало излишним, и большинство современных программ не используют
эту возможность языка.
Более того, программы, использующие ключевое слово register,
могут проигрывать в эффективности,
поскольку программисты — не лучшие знатоки в низкоуровневых вопросах наподобие
распределения регистров. Выбор оптимального распределения регистров очень
сильно зависит от архитектуры конкретной машины. Следование принятым
программистом решениям о низкоуровневом распределении ресурсов может в
действительности привести к падению производительности, в особенности при
работе программы на других машинах, а не на той, для которой она создавалась.
Многие распространенные языки программирования
смещаются в сторону увеличения уровня абстракции. Доминирующим языком
программирования в 1980-е годы был С, но уже в 1990-х годах во многих новых
проектах использовался язык программирования С++; разработанный в 1995 году
язык программирования Java быстро
приобрел популярность к концу 1990-х годов. Новые возможности языков
программирования приводили к новым исследованиям в области оптимизации кода.
Далее будут рассмотрены основные возможности языков программирования, которые
стимулировали значительное развитие технологий компиляции.
Практически все распространенные языки
программирования, включая С, Fortran
и Cobol, поддерживают определяемые пользователем агрегированные типы данных, такие
как массивы и структуры, а также высокоуровневые средства управления потоком
выполнения, такие как циклы и вызовы процедур. Если ограничиться
непосредственной трансляцией каждой высокоуровневой конструкции или операции
обращения к данным, результат получится очень неэффективным. Разработанная
оптимизация потоков данных (data-flow optimization) анализирует потоки данных в программе и удаляет избыточность таких
конструкций. Она генерирует код, который напоминает код, написанный на низком
уровне профессиональным программистом.
Объектная
ориентированность впервые появилась в языке Simula в 1967 году и вошла в такие языки, как Smalltalk, С++, С# и Java.
Ключевыми идеями, лежащими в основе
объектной ориентированности, являются
- абстракция данных;
- наследование
свойств.
Они делают программы более модульными и упрощают их поддержку. Объект-
но-ориентированные программы отличаются от программ, написанных на других
языках
программирования, тем, что они состоят из большего количества процедур
меньшего размера (которые в объектно-ориентированном программировании
называются методами). Таким образом, оптимизация должна быть способна перешагнуть
границы процедур в исходной программе. Здесь оказалось особенно полезным
встраивание процедур, представляющее собой замену вызова процедуры ее телом.
Была также разработана оптимизация, ускоряющая диспетчеризацию виртуальных
методов.
Java
обладает многими облегчающими
программирование возможностями, которые появились ранее в других языках
программирования. Язык Java безопасен с
точки зрения типов, т.е. объект не может использоваться вместо объекта несвязанного
типа. Обращение к массивам выполняется с проверкой выхода за пределы массива. Java
не имеет указателей и не использует
соответствующую арифметику. Этот язык программирования имеет встроенную систему
сборки мусора, которая автоматически освобождает выделенную для переменных
память, которая больше не используется. Все эти возможности упрощают
программирование, но приводят к дополнительным накладным расходам времени
выполнения. Разработанная для языка программирования Java оптимизация снижает накладные расходы, например, устраняя излишние
проверки диапазонов и выделяя память для объектов, недоступных извне процедуры,
в стеке, а не в куче. Разработаны также эффективные алгоритмы для минимизации
накладных расходов по сборке мусора.
Кроме
прочего, язык программирования Java разработан
для поддержки переносимости и мобильного кода. Программы распространяются в
виде байт-кода Java,
который либо интерпретируется, либо
компилируется в машинный код динамически, т.е. в процессе выполнения.
Динамическая компиляция изучалась также и в других контекстах, когда информация
извлекается динамически, во время выполнения, и используется для получения
более оптимизированного кода. При такой динамической оптимизации важно
минимизировать время компиляции, которое является частью накладных расходов
выполнения программы. Распространенная методика состоит в компиляции и
оптимизации только тех частей программы, которые будут часто выполняться.
Комментариев нет:
Отправить комментарий