-
Notifications
You must be signed in to change notification settings - Fork 35
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Оптимизация результатных выражений #16
Comments
СоображениеОптимизация построения результатных выражений предполагает повторное использование фрагментов вызова функции для построения результата. Следовательно, (а) при сопоставлении образцов должны запоминаться позиции отдельных его фрагментов (хотя бы тех, которые будут использоваться в результате), (б) при генерации команд построения результата должна быть известна информация о том, какие части результата заимствуются из образца, какие создаются заново. СейчасСейчас (в состоянии без оптимизации) фрагментами, которые могут (и должны быть!) заимствованы из вызова функции — это переменные. Часть переменных в результатном выражении берутся из аргумента, часть должны быть скопированы. Информация о том, какие переменные должны быть скопированы (и какие не должны были сопоставляться) определяется уже после (!) анализа образцового и результатного выражений. Операции сопоставления с образцом фильтруются на предмет избыточных сопоставлений с закрытыми переменными (ранее они приводили к предупреждениям компилятора C++). Операции построения результата дополняются командами копирования. Что надо сделатьЧтобы реализовать оптимизацию, нужно изменить подход. Возможны два варианта. Либо функция сопоставления с образцом ( Либо сначала отдельной функцией обходится и образец, и результат, при этом в том и другом помечаются, соответственно, сохраняемые и переиспользуемые фрагменты, а затем функции Оба варианта приемлемы. Но надо помнить: задачей курсового является, прежде всего, написание той новой функции, которая будет выбирать для результата переиспользуемые фрагменты образца. |
Во-первых, код стал более линейным, без кучи вложенных функций. Во-вторых, переписан с использованием библиотеки GetOps. В-третьих, появились опции, управляющие процессом компиляции: * опция -O для включения оптимизации (-OP для образцов, -OR для результатов), * опция --gen для выбора режима кодогенерации (both, direct или interp). Пока новые опции никак не обрабатываются.
Команды сопоставления имели формат: (s.Command s.Direction s.Range e.Info) Функция FreezeRanges ожидала, что номер диапазона будет третьим термом, и, таким образом, поправляла его значение. Новые команды сопоставления получили следующий формат: (s.Command s.ElemOffset s.Direction s.Range e.Info) FreezeRange уже не могла поправлять номер диапазона. Для исправления ошибки добавлен частный случай в функцию FreezeRange.
Пример кода ранее был ошибочным, теперь ошибка исправлена. Формат команд сохранения должен быть: (s.Command s.Direction s.Range s.ElemOffset e.Info) Важно: s.Range должен быть третьим термом — там его ожидает увидеть функция FreezeRanges.
Результаты (кратко):
Детали — в записке. |
Текущая реализация компилятора использует классическое списковое представление данных. Это значит, что поле зрения (которое по определению является активным выражением) представляет собой единый двусвязный список, отдельным элементам которого соответствуют атомы и три вида скобок (скобки имеют дополнительные связи между собой). Также имеется и список свободных узлов, из которого берутся новые узлы для построения новых значений и куда помещаются использованные узлы. При недостатке узлов этот список автоматически пополняется новыми узлами, полученными путём выделения динамической памяти функцией
malloc()
.Выполнение функции условно можно разбить на два этапа: анализ аргумента и построение результата. Анализ осуществляется путём последовательного перебора левых частей предложений на предмет соответствия аргумента одному из образцов (анализ в настоящей задаче не рассматривается). Построение результата — формирование возвращаемого значения функции — представляет собой создание нового фрагмента двусвязного списка, который будет замещать список-вызов функции в поле зрения.
В текущей реализации результат формируется из переменных, присутствующих в образце и новых узлов (литеральных значений атомов и скобок), формируемых в списке свободных узлов. При этом, ожидаемо, что если в правой части у некоторой переменной вхождений больше, чем в левой, недостающие экземпляры переменной формируются в списке свободных узлов. Затем, оставшаяся часть вызова функции (скобки вызова функции + имя функции + остаток аргумента, из которого изъяны переменные для результатного выражения) переносится в список свободных узлов.
В данном случае есть две причины потери производительности:
Примечание. Данное исследование уже проводилось в 2010 году (коммит 6af96b3, не в master’е). В ходе исследования удалось выяснить, что уйма времени тратится на перевязывание отдельных узлов, если переносить созданные элементы целыми фрагментами, то производительность резко повышается. Также исследование показало, что если сохранять ссылки на отдельные узлы аргумента и вместо нового создания в списке свободных узлов использовать такие же из аргумента, то статистически значимого прироста производительности это не даёт. Алгоритм, который позволяет минимальным числом правок преобразовать вызов функции в результат, не разрабатывался.
Минимизация числа переносов уже была реализована в Модульном Рефале, прирост производительности составил порядка 13 %. В основной ветке Простого Рефала такой оптимизации на данный момент нет, код из исследования 2010 года не применялся в основной ветке, поскольку написан относительно грязно и содержит кучу артефактов исследования.
Программа минимум — это минимизация количества переносов, должна быть реализована по-любому. Главное, что требуется реализовать — алгоритм, который преобразует вызов функции в её результат путём минимального числа модификаций.
Романенко в своей диссертации от 1978 года предлагает
алгоритм оптимизации построения результатных выражений, однако описывает его лишь в общих чертах.
Диссертация Романенко:
The text was updated successfully, but these errors were encountered: