Генерация высококачественного кода для программ, написанных на СИ - [2]

Шрифт
Интервал

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

Процедуры - это операторы, которые содержат целые подпрограммы или функции. Оптимизация на этом уровне вообще не выполняется компиляторами для PC.

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

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

Исходный текст конкретного языка первым делом транслируется в общую промежуточную форму, которая последовательно обрабатывается для выработки на стадии генерации машинно-зависимого кода. Машинно-независимая оптимизация, такая как выделение общих подвыражений и вынесение инвариантного кода, применяется к промежуточному коду. Машинно-зависимая оптимизация применяется к результату стадии генерации кода и использует набор команд конкретного процессора. Эта оптимизация известна как "щелевая" оптимизация, потому что эти преобразования выполняются внутри маленького окна (5 - 10 инструкций машинного уровня). Типичные примеры щелевой оптимизации включают удаление излишних операций загрузки/сохранения регистров, удаление недостижимого кода, выпрямление передач управления, алгебраические упрощения, снижение мощности (команд) и использование команд, специфических для конкретного процессора.

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

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

>x = 2;

> if( a < x && b < x)

> c = x;s

переводится в

>x = 2;

>if(a < 2 && b < 2)

> c = 2;

Целиком связано с размножением констант "размножение копий". В этом методе копируются переменные вместо константных значений. Например,

>x = y;

>if(a < x && b < x)

> c = x;

переводится в

>x = y;

>if(a < y && b < y)

> c = y;

Размножение констант и копий также может удалить излишние присваивания (x = 2 и x = y в примерах). Среди описываемых компиляторов только Microsoft C 5.0 и WATCOM C 6.0 применяют размножение констант.

Метод "свертки констант" (константная арифметика) сводит выражения, которые содержат константные данные, к возможно простейшей форме. Константные данные обычно используются в программе либо непосредственно (как в случае чисел или цифр), либо косвенно (как в случае объявленных манифестных констант). Свертка констант сводит следующий оператор:

>#define TWO 2

>a = 1 + TWO;

к его эквивалентной форме,

>a = 3;

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

"Алгебраические упрощения" есть вид свертки констант, который удаляет арифметические тождества. Код, сгенерированный для таких операторов, как

>x = y + 0;

>x = y * 0;

>x = y / 1.0;

>x = y / 0;

должен быть простым константным присваиванием и не должен содержать команд для выполнения арифметических операций. Бдительный компилятор должен пометить последний оператор как ошибочный и не генерировать код для него.

"Извлечение общих подвыражений" - это процесс удаления лишних вычислений. Вместо того, чтобы генерировать код для вычисления значения каждый раз, когда оно используется, оптимизирующий компилятор пытается выделить выражение таким образом, чтобы его значение вычислялось только однажды. Там, где это возможно, последующие ссылки на такое же выражение используют ранее вычисленное значение. Выражения y * 3 и a[y*3] являются общими подвыражениями в следующем тексте:

>if( a[y*3] < 0 || b[y*3] > 10)

> a[y*3] = 0;

Выделение этих выражений приводит к логически эквивалентному тексту:

>T1 = y*3;

>A1 = &a[T1];

>A2 = &b[T1];

>if( *A1 < 0 || *A2 > 10)

> *A1 = 0;

Выделение общих подвыражений обычно происходит внутри оператора или блока. "Глубокое выделение общих подвыражений" является более сложным и перекрывает базовые блоки. Выделение общего подвыражения, y*3, в операторе


Рекомендуем почитать
Графика для Windows средствами DirectDraw

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


Виртуальная библиотека Delphi

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


Пишем драйвер Windows на ассемблере

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


Как писать драйвера

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


MFC и OpenGL

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


Информационная технология. Оценка программной продукции характеристики качества и руководства по их применению

Стандарт подготовлен на основе применения аутентичного текста международного стандарта ИСО/МЭК 9126-91 «Информационная технология. Оценка программной продукции. Характеристики качества и руководства по их применению»Information technology. Software product evaluation. Quality characteristics and guidelines for their use.