Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ТЯП_шпоры.doc
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
3.21 Mб
Скачать

Вопрос 43

Оптимизация логических выражений

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

Определение 4.19. Операция называется предопределенной для некоторого значения операнда, если ее результат зависит только от этого операнда и остается неизменным (инвариантным) относительно значений других операндов.

Пример 4.17. Операция логического сложения (or) является предопределенной для логического значения «истина» (true), а операция логического умножения (and) предопределена для логического значения «ложь» (false).

Поэтому, например, выражение А and В and С and D не имеет смысла вычислять, если известно, что значение переменной А есть false.

Оптимизация циклов

Для оптимизации циклов используются следующие методы:

- вынесение инвариантных вычислений из циклов;

- замена операций с индуктивными переменными;

- слияние и развертывание циклов.

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

Пример 4.18. Рассмотрим цикл for i:=l to 100 do K[i]:= K[i]/(A*B).

После применения оптимизирующего преобразования цикл будет иметь вид:

C:= A*B;

for i:=l to 100 do K[i]:= K[i]/C.

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

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

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

Пример 4.18. Рассмотрим цикл for i:=l to N do K[i]:=i*100.

После применения оптимизирующего преобразования, цикл будет иметь вид:

T:= 100; i:= 1;

while i<=N do

begin

K[i]:= T;

T:= T+100;

i:= i +1;

end;

Слияние циклов предусматривает замену двух вложенных циклов одним.

Пример 4.19. Рассмотрим фрагмент программы, инициализирующий двумерный массив:

for i:=l to N do

for j:=l to M do A[i, j]:=0.

С точки зрения объектного кода (но не с позиции семантики исходного языка) двумерный массив - это область памяти размером N*M, поэтому данную операцию можно представить так:

К:= N*M;

for i:=1 to К do A[i]:= 0.

Развертывание циклов – это замена цикла линейной последовательностью операций. Данную замену можно выполнить для циклов, кратность выполнения которых известна уже на этапе компиляции. Тогда цикл, кратностью N, можно заменить линейной последовательность N операций, содержащих тело цикла.

Пример 4.20. Цикл for i:=1 to 3 do A[i]:= i* i можно заменить операциями:

A[1] := 1; A[2] := 4; A[3] := 9.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]