Динамическая генерация кода

Введение в динамическую генерацию кода. Отображение абстрактного синтаксиса выражений в CIL. Оптимизация линейных участков кода. Peephole-оптимизация и генерация развилок, содержащих инструкции переходов. Абстрактный синтаксис логических выражений.

Рубрика Программирование, компьютеры и кибернетика
Вид курсовая работа
Язык русский
Дата добавления 19.05.2009
Размер файла 38,6 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Курсовая работа

По дисциплине: «Системное программирование»

На тему «Динамическая генерация кода»

2009

Оглавление

1. Введение в динамическую генерацию кода

2. Абстрактный синтаксис выражений

3. Отображение абстрактного синтаксиса выражений в CIL

3.1 Оптимизация линейных участков кода

3.2 Генерация развилок

4. Абстрактный синтаксис логических выражений

1. Введение в динамическую генерацию кода

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

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

В некотором смысле, любой JIT-компилятор как раз использует динамическую генерацию кода: имея некоторую программу, записанную на промежуточном языке (байт-коде), и зная, какой процессор работает в системе, JIT-компилятор динамически транслирует программу в инструкции этого процессора. При этом можно считать, что тип процессора - эта как раз та часть информации, которая становится известной только во время выполнения программы.

Естественно, не стоит чересчур увлекаться динамической генерацией кода: этот прием далеко не всегда дает ускорение программы. Можно сказать, что применение динамической генерации оправдано, если:

процесс вычислений в некотором фрагменте программы преимущественно определяется информацией, известной только во время выполнения;

запуск этого фрагмента осуществляется многократно;

выполнение фрагмента связано с существенными затратами времени процессора.

В .NET доступно два способа организации динамической генерации кода:

порождение программы на языке C# и вызов компилятора C#;

непосредственное порождение метаданных и CIL-кода.

Если сравнить эти два способа, можно придти к выводу, что порождение C#-программы несколько проще, нежели генерация CIL-кода.

Однако, наличие в библиотеке классов пространства имен System.Reflection.Emit позволяет избежать рутинных и трудоемких операций по работе с физическим представлением метаданных и CIL-кода. Кроме того, генерация CIL-кода выполняется на порядок быстрее и дает большую гибкость. Поэтому для программиста, знакомого с набором инструкций CIL, второй способ является более предпочтительным.

2. Абстрактный синтаксис выражений

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

Пусть абстрактный синтаксис для наших выражений содержит правила, приведенные в таблице 5.2.

Таблица 5.2. Абстрактный синтаксис выражений

Правило

Описание

Expr ::= const c

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

Expr ::= local x

Локальная переменная с именем х

Expr ::= arg x

Параметр метода с именем х

Expr ::= Expr index Expr

Доступ к элементу массива. Здесь первое выражение должно возвращать ссылку, а второе - целое число, означающее индекс элемента

Expr ::= Expr field f

Доступ к полю f объекта

Expr ::= minus Expr

Унарный минус

Expr ::= Expr BinOp Expr

Бинарная арифметическая операция

Expr ::= local ? assign Expr

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

Expr ::= arg ? assign Expr

Операция присваивания параметру х значения выражения

Expr ::= Expr index Expr assign Expr

Операция присваивания элементу массива значения выражения

Expr ::= Expr field f assign Expr

Операция присваивания полю f объекта значения выражения

Expr ::= Expr call s Arglist

Вызов экземплярного метода s для некоторого объекта с передачей списка фактических параметров

Arglist ::= Expr Arglist

Непустой список фактических параметров метода

Arglist ::= пусто

Пустой список фактических параметров метода

BinaryOp ::= plus

Сложение

BinaryOp ::= minus

Вычитание

BinaryOp ::= mul

Умножение

BinaryOp ::= div

Деление

3. Отображение абстрактного синтаксиса выражений в CIL

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

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

GenExpr[const c] = нужный вариант инструкции ldc;

GenExpr[local x] = ldloc x;

GenExpr[arg x] = ldarg x;

GenExpr[Expr1 index Expr2] =

GenExpr[Expr1],

GenExpr[Expr2],

ldelem.нужный тип;

GenExpr[Expr field f] =

GenExpr[Expr],

ldfld f;

GenExpr[minus Expr] =

GenExpr[Expr],

neg;

GenExpr[Expr1 BinOp Expr2] =

GenExpr[Expr1],

GenExpr[Expr2],

GenBinOp[BinOp];

GenExpr[local x assign Expr] =

GenExpr[Expr],

dup,

stloc x;

GenExpr[arg x assign Expr] =

GenExpr[Expr],

dup,

starg x;

GenExpr[Expr1 index Expr2 assign Expr3] =

GenExpr[Expr1],

GenExpr[Expr2],

GenExpr[Expr3],

dup,

stloc временная переменная,

stelem.нужный тип,

ldloc временная переменная;

GenExpr[Expr1 field f assign Expr2] =

GenExpr[Expr1],

GenExpr[Expr2],

dup,

stloc временная переменная,

stfld f,

ldloc временная переменная;

GenExpr[Expr call s ArgList] =

GenExpr[Expr],

GenArgList[ArgList],

call(callvirt) s;

GenArgList[Expr ArgList] =

GenExpr[Expr],

GenArgList[ArgList];

GenArgList[пусто] = ;

GenBinOp[plus] = add;

GenBinOp[minus] = sub;

GenBinOp[mul] = mul;

GenBinOp[div] = div;

3.1 Оптимизация линейных участков кода

Рис. 5.1.  Peephole-оптимизация

Зачастую бывает удобно разделить фазы генерации и оптимизации кода. Это позволяет существенно упростить генератор, сделать его независимым от оптимизатора и, кроме того, повторно использовать оптимизатор с другими генераторами.

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

Суть peephole-оптимизации заключается в том, что оптимизатор ищет в коде метода сравнительно короткую последовательность инструкций, удовлетворяющую некоторому образцу, и заменяет ее более эффективной последовательностью инструкций.

Алгоритм peephole-оптимизации использует понятие фрейма. Фрейм можно представить как окошко, двигающееся по коду метода. Содержимое фрейма сравнивается с образцом, и в случае совпадения выполняется преобразование (см. рис. 5.1).

Peephole-оптимизация линейного участка кода должна выполняться многократно до тех пор, пока на очередном проходе фрейма по этому участку кода не будет найдено ни одного образца. С другой стороны, алгоритм peephole-оптимизации может быть остановлен в любой момент, что позволяет добиться требуемой скорости работы оптимизатора.

В таблице 5.3 приведен список некоторых образцов и замен, которые можно использовать для peephole-оптимизации CIL-кода.

Таблица 5.3. Некоторые образцы и замены для peephole-оптимизации CIL-кода

Образец

Замена

stloc(starg) x

ldloc(Ldarg) х

dup

stloc(starg) x

ldloc(ldarg) x

ldloc(ldarg) x

ldloc(ldarg) x

dup

ckfinite

ckfinite

ckfinite

not(neg)

pop

pop

add(sub, mul, div,...)

pop

pop

pop

idc.i4.0

add(sub)

-

ldloca(ldarga) x

initobj int32

idc.i4.0

stloc(starg) x

stloc(starg) x

ldloc(ldarg) y

ldloc(ldarg) x

add (или любая коммутативная бинарная операция)

dup

stloc(starg) x

ldloc(ldarg) y

add (или любая коммутативная бинарная операция)

3.2 Генерация развилок

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

Интересен факт, что генерация развилок существенно упрощается, если в процессе генерации придерживаться определенных требований структурированной парадигмы в программировании. Эти требования заключаются в том, что в генерируемой программе используются только пять структурных конструкций, а именно: последовательность (рис. 5.2a), выбор (рис. 5.2b), множественный выбор (рис. 5.2c), цикл с предусловием (рис. 5.2d) и цикл с постусловием (рис. 5.2e). При этом конструкции могут быть вложены друг в друга.

Рис. 5.2.  Peephole-оптимизация

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

4. Абстрактный синтаксис логических выражений

Будем рассматривать логические выражения, которые содержат арифметические выражения, рассмотренные ранее, в качестве подвыражений. Пусть также логические выражения содержат операции сравнения (равно, меньше, больше) и логические операции (логическое И, логическое ИЛИ, логическое НЕ).

Дополним абстрактный синтаксис выражений, приведенный ранее в данной главе, новым нетерминалом LogExpr. Правила для этого нетерминала приведены в таблице 1.

Таблица 1. Абстрактный синтаксис логических выражений

Правило

Описание

LogExpr ::= Expr

Вырожденный случай, когда логическое выражение не содержит ни одной логической операции или операции сравнения

LogExpr ::= LogExpr

ComparisonOp LogExpr

Сравнение двух выражений

LogExpr::= LogExpr

and LogExpr

Применение логического И

LogExpr::= LogExpr

or LogExpr

Применение логического ИЛИ

LogExpr ::= not LogExpr

Применение логического НЕ

ComparisonOp ::= equal

Равенство

ComparisonOp ::= less

Меньше

ComparisonOp ::= greather

Больше


Подобные документы

  • Генерация порождающего полинома для циклического кода. Преобразование порождающей матрицы в проверочную и обратно. Расчет кодового расстояния для линейного блокового кода. Генерация таблицы зависимости векторов ошибок от синдрома для двоичных кодов.

    доклад [12,6 K], добавлен 11.11.2010

  • Процесс создания программы, разработка проекта программы и программирование. Лексическая обработка, синтаксический анализ, поэтапная генерация кода, использование библиотечного файла и кода. Стандартные функции библиотечного кода, математические ошибки.

    курсовая работа [26,4 K], добавлен 01.12.2009

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

    дипломная работа [5,0 M], добавлен 08.06.2017

  • Общее описание и особенности использования программы, предназначенной для определения нечетных чисел, находящихся в массиве чисел. Листинг и методы оптимизации данной компьютерной программы. Источники оптимизации кода, описание выполненных команд.

    лабораторная работа [17,4 K], добавлен 25.03.2011

  • Современные концепции и технологии проектирования операционных систем. Управление процессами и оперативной памятью. Трансляция программ, генерация кода. Формальное определение языков программирования. Лексический, синтаксический, семантический анализ.

    методичка [219,8 K], добавлен 15.02.2012

  • Краткая характеристика предметной области. Создание диаграммы прецедентов, последовательности, сотрудничества, классов, размещения, компонентов. Добавление деталей к описаниям операций и определение атрибутов КЛАССОВ. Генерация программного кода C++.

    курсовая работа [185,0 K], добавлен 29.06.2011

  • Исследование системы функционирования зоомагазина "Дракоша" и схематическое описание бизнес-процессов предприятия. Генерация кода и разработка автоматизированной информационной системы магазина на языке программирования С+. Расчет диаграмм автоматизации.

    курсовая работа [841,8 K], добавлен 07.08.2013

  • Исследование объектно-ориентированного подхода к проектированию программного обеспечения будильника. Модель программного обеспечения. Взаимодействие между пользователями и системой. Диаграммы и генерация программного кода при помощи средств Rational Rose.

    курсовая работа [355,8 K], добавлен 26.09.2014

  • Проектирование преобразователя кода (ПК), рассчет его энергопотребления и быстродействия. Составление таблицы истинности ПК. Написание булевых функций, минимизация и преобразование к выбранному базису. Составление структурной схемы преобразователя кода.

    курсовая работа [775,3 K], добавлен 09.02.2009

  • Изучение синтаксиса пользовательских функций. Разработка приложения для вычисления параметров системы управления запасами. Синтаксис элемента "Список аргументов функции". Основные правила написания программного кода. Основные операторы языка VBA.

    лабораторная работа [119,0 K], добавлен 22.09.2016

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.