Знакомимся с GCC 4

Новшества, доступные с выходом этой ветки GNU-компиляторов

Переход от версии 3 к версии 4 - важный шаг в развитии набора компиляторов GNU (GCC). Такие нововведения как обновленная подсистема оптимизации, поддержка новых платформ, языков, атрибутов и опций доступны в GCC 4. Данная статья познакомит с основными новшествами и их преимуществами.

М. Тим Джонс, инженер-консультант, Emulex

M. Тим Джонс (M. Tim Jones) является архитектором встраиваимого программного обеспечения и автором работ: Программирование Приложений под GNU/Linux, Программирование AI-приложений и Использование BSD-сокетов в различных языках программирования. Он имеет опыт разработки процессоров для геостационарных космических летательных аппаратов, а также разработки архитектуры встраиваемых систем и сетевых протоколов. Сейчас Тим работает инженером-консультантом в корпорации Эмулекс (Emulex Corp.) в г.Лонгмонт, Колорадо.



27.11.2008

GCC является краеугольным камнем в мире разработчиков ПО как с открытым кодом, так и традиционного. GCC дает путевку в жизнь архитектурам и операционным системам. Когда выходит новый процессор, его успех зависит от того, появится ли его поддержка в будущих версиях GCC (точнее, появится ли модуль GCC, способный создавать для него код). Linux® своему успеху обязан также GCC. Возможность запуска на многих архитектурах - основная причина популярности Linux. Следовательно, появление в GCC поддержки новой платформы позволяет портировать и запустить Linux на этой платформе. Скажем прямо - GCC является гарантом развития Linux и встраиваемых систем.

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

Краткая история

В 1987 году Ричард Столлман выпустил компилятор языка C, который он назвал GNU C Compiler, или кратко - GCC. (История развития GCC показана на на рисунке 1). В 1984 году Ричард начал работу над созданием компилятора языка C, который можно было бы свободно использовать, модифицировать и развивать. Изначально GCC работал на ранних системах Sun и DEC VAX.

Так как исходники компилятора Столлмана были доступны всем, другие люди время от времени исправляли дефекты и, что самое главное, добавляли поддержку новых языков и архитектур. Вскоре GCC стал расшифровываться как GNU Compiler Collection (набор компиляторов GNU), поскольку уже имел поддержку многих языков для наиболее распространенных на то время архитектур.

Рисунок 1. История современных версий GCC
История современных версий GCC

GCC - самый популярный на сегодня инструмент разработки. Компиляторы различных языков (Ada, Fortran, Java™, C и его разновидности - C++ и Objective-C), входящие в его состав, имеют в основе общий код, что позволяет легко создать компилятор нового языка. По сравнению с конкурентами, GCC способен транслировать код для наибольшего числа процессоров (около 30 семейств) с любого из поддерживаемых языков. Базовый исходный код GCC полностью переносим и работает на более чем 60 платформах. Компиляторы GCC обладают высокой гибкостью и поддерживают множество опций для тонкой настройки генерируемого кода. GCC поражает своей универсальностью и напоминает многофункциональный складной нож. Наконец, он является, пожалуй, самым сложным существующим открытым проектом: сейчас его исходный код насчитывает около 1.5 миллиона строк.

Ну и ну! Вам уже кажется, что я обожаю GCC больше, чем свою жену? Скажем так, если она входит в комнату, когда я программирую с GCC, мне становится чуток не по себе.


Небольшое введение

Обычно компиляторы работают по принципу конвейера, а между отдельными стадиями передаются различные виды данных (см. рисунок 2). Начальная стадия (front end) зависит от языка программирования - на ней происходит синтаксическое распознавание исходного кода и преобразование к структурам на основе деревьев и промежуточному RTL-представлению (RTL - Register Transfer Language, язык межрегистровых пересылок). Конечная стадия (back end) принимает с предыдущей стадии языко-независимые RTL-инструкции и создает код, работающий на определенной платформе. При этом RTL-код подвергается оптимизации для получения максимально быстрого либо компактного кода (а если возможно, то и того, и другого), после чего направляется на вход генератора кода конкретной платформы.

Рисунок 2. Упрощенная схема работы компилятора
Упрощенная схема работы компилятор

Ключевые новшества GCC 4

Четвертая версия привнесла множество изменений в компиляторы GCC, но основное - это улучшенная оптимизация и применение SSA-представлений на основе деревьев (SSA - Static Single Assignment, статическое одноразовое присвоение). Улучшений много, а главное - некоторые режимы оптимизации стали давать более быстрый код и появилась поддержка новых целевых платформ. Также улучшился вывод предупреждений и сообщений об ошибках (например, в ряде случав одни и те же ситуации вызывают уже не предупреждение, как в GCC 3, а ошибку). Но появилось и неудобство: объектные файлы, полученные с помощью GCC 3, несовместимы с GCC 4, поэтому их придется перекомпилировать. Смиримся с этим, так как никакой прогресс не дается даром.

Остановимся подробнее на главных улучшениях, идущих с GCC 4.

Версии на основе 4.0

С этой веткой пришли главные изменения, а завершилась она на 4.0.4. Эти версии не объявлены стабильными, поэтому их не рекомендуется использовать для серьезных целей. Изменений множество, но главное - это появление новой модели оптимизации (SSA-формы на основе деревьев) и поддержки автовекторизации.

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

Применение SSA-форм предполагает наличие двух промежуточных представлений. Первое называется GENERIC, состоящее из обычных деревьев, полученных в свою очередь из деревьев исходного текста. Далее GENERIC-деревья преобразуются в GIMPLE-представление и создается граф управляющей логики, необходимый для оптимизации при помощи SSA. Затем SSA-деревья преобразуются в RTL-формы, которые передаются на вход модуля генерации платформенно-зависимого кода. В действительности все не так просто, но смысл состоит именно в появлении новой промежуточной стадии, дающей более эффективную оптимизацию на разных уровнях. (В разделе Ресурсы приведены ссылки на подробную информацию.)

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

Еще одно интересное новшество GCC 4 - векторизатор циклов, основанный на SSA. Появилась автовекторизация, т.е. автоматическое нахождение последовательных циклов и попытка реализовать их при помощи векторных команд выбранной целевой платформы. В результате получается более компактный и эффективный код. Появился еще один вид оптимизации циклов, который называется планирование на основе свободных модулей (Swing Modulo Scheduling, SMS). Он позволяет загружать конвейер команд процессора таким образом, чтобы минимизировать количество циклов за счет параллелизма на уровне команд. Подробные сведения об этих и других новшествах доступны по ссылкам из раздела Ресурсы.

Наконец, в версии 4.0 обновлен языковой модуль Fortran, поддерживающий не только старый Fortran 77 (как GCC 3), но и Fortran 90 и 95. Множество изменений претерпел C и C++. Также отражены особенности языка Ada 2005 и реализована поддержка Ada на большем количестве целевых платформ.

Версии на основе 4.1

Уже имея новую модель оптимизации, начиная с версии 4.1 мы встречаем еще больше видов оптимизации, таких как улучшенная поддержка профилирования и более точная оценка вероятности ветвления. Еще два полезных улучшения - усовершенствованная поддержка inline-функций и способность эффективно использовать наличие разных уровней кэша инструкций. Например, гораздо лучше создавать как inline только функции те, которые вызываются часто, а не все подряд. Поэтому компилятор теперь применяет inline только к "ходовым" участкам кода, в результате чего мы имеем все преимущества inline-вызовов, а получаемый код остается небольшим. Помимо этого GCC классифицирует участки кода на "горячие" (часто используемые) и "холодные" (редко используемые). Код первых группируется вместе, что дает более оптимальную работу кэша инструкций, так как присутствие редких функций в кэше снижает его эффективность.

Языковой модуль претерпел изменения; в частности, был добавлен интерпретатор Objective-C++. Множество обновлений было сделано для базовой библиотеки Java (libgc). В модуль генерации кода добавлена начальная поддержка процессора IBM® System z™ 9-109, которая включает в себя операции с 128-разрядными числами с плавающей запятой (согласно стандарту IEEE - Institute of Electrical and Electronics Engineers, Институт инженеров по электротехнике и электронике) и встроенные атомарные операции с памятью. И это далеко не все. Теперь в создаваемый двоичный код можно добавить защиту от атаки на срыв стека, что достигается путем обнаружения переполнения буферов и благодаря переупорядочиванию данных во избежание порчи указателей. Некоторые встроенные функции также были наделены защитой от переполнения буферов, однако это не сильно сказалось на скорости их работы.

Версии на основе 4.2

В этой версии улучшения продолжаются - и в области оптимизации, и в сфере поддерживаемых языков и процессорных архитектур. Теперь можно получать код для процессора Sun UltraSPARC T1 (кодовое имя Niagara) и Broadcom SB-1A с MIPS-ядром.

В версии 4.2 изменения не обошли стороной и языковой модуль: подвергся рефакторингу механизм работы с областями видимости в C++, а также появилась поддержка расширений потокового ввода/вывода для Fortran 2003. Но самое интересное - в компиляторах C, C++ и Fortran добавлен интерфейс OpenMP, реализованный на основе потоков. За счет OpenMP в получаемом коде достигается параллелизм инструкций и данных.

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

Рисунок 3 иллюстрирует, как указанный метод работает на практике. OpenMP имеет не только свои директивы препроцессора (pragma), но и функции для C, C++ и Fortran. На рисунке 3 показана простая программа, содержащая цикл for, который распараллеливается на несколько потоков. Эффект от OpenMP представлен графически: в традиционной программе цикл выполняется последовательно, итерация за итерацией, в то время как в программе с OpenMP блок for работает параллельно. Подробнее ознакомиться с OpenMP можно по ссылкам из раздела Ресурсы.

Рисунок 3. Простой пример применения OpenMP
Простой пример применения OpenMP

Версии на основе 4.3

Это текущая ветка GCC, в которой функциональность продолжает расти, как и поддержка новых архитектур (вместе с тем удаляются некоторые устаревшие и не поддерживаемые разработчиками архитектуры и платформы). Улучшена поддержка языка Fortran 2003, а оптимизатор получил новые заметные усовершенствования.

Среди новых поддерживаемых платформ отметим некоторые процессоры семейства Coldfire, процессор IBM System z9 EC/BC, высокопроизводительный блок синергетических процессоров (Synergistic Processor Unit, SPU) архитектуры Cell, SmartMIPS и многие другие. Компилятор и библиотеки GCC теперь поддерживают Thumb2 (разновидность архитектуры ARM c сокращенным командным словом) и ARMv7. Улучшения затронули также поддержку процессоров Core2 и Geode.

Что касается верхнего уровня в целом, то была переопределена внутренняя структура GIMPLE-представления, после чего компилятор стал потреблять меньше памяти.

Версии после 4.3

Уже начата работа над версией 4.4, которая скоро станет основной веткой. В ней будет исправлено множество дефектов и улучшен оптимизатор. Реализована спецификация OpenMP 3.0 для языков C, C++ и Fortran.

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

И, наконец, добавлена поддержка нового 16-разрядного многоядерного процессора Picochip. Этот процессор интересен тем, что его ядра программируются независимо и образуют многосвязную топологию.


Что дальше?

Очевидно, GCC ждет успешное будущее. Компиляторы продолжают развиваться - как в плане своей архитектуры, так и в плане функциональности, и охватывают все больше современных процессоров и платформ. Да и охват языков программирования поистине велик. На стадии разработки находятся еще несколько языков, включая Mercury, GHDL (GCC-вариант VHDL) и Унифицированный Параллельный C (Unified Parallel C).

Как результат прогресса GCC, нас ждет и улучшение качества самого разного ПО - Linux, Berkeley Software Distribution (BSD), Apache и многого другого. Код, скомпилированный GCC4, выигрывает в скорости и размере, что наилучшим образом отразится на всей отрасли программного обеспечения.

Ресурсы

Научиться

Получить продукты и технологии

  • Разработайте ваш следующий Linux-проект с помощью пробного ПО от IBM (EN), доступного для загрузки прямо с developerWorks.

Обсудить

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Linux
ArticleID=355024
ArticleTitle=Знакомимся с GCC 4
publish-date=11272008