-
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
Версия 3.4 #361
base: master
Are you sure you want to change the base?
Версия 3.4 #361
Conversation
Ранее специализация замыкания {{ &F CONTENT }} осуществлялась как специализация фиктивного вызова <F CONTENT e.@>. Оптимизатор строил новый вызов <F@1 CONTENT′ e.@>, из которого восстанавливалось замыкание {{ &F@1 CONTENT′ }}. Добавлять и удалять фиктивную переменную e.@ было безопасно, т.к. она была в позиции динамического параметра, позиция параметра не менялась (оставалась последней) и во внутрь функции она не протекала. Теперь же при специализации это имя может протечь внутрь экземпляра, внутри экземпляра может оказаться другое замыкание, в контексте которого будет переменная e.@. Добавление e.@ в конец вызовет конфликт имён. ---- В коде есть некоторый костыль, который проистекает из отсутствия поддержки подавления предупреждений. Исходники намеренно собираются с -Werror, а в данном коде было бы разумно явно добавить «подозрительную» (#290) повторную переменную. Пришлось достигать эту проверку более громоздким куском исходного кода.
Самоприменение выполняется в режиме set RLMAKE_FLAGS=-X-OiDPRS
До оптимизации после самоприменения в режиме: set RLMAKE_FLAGS=-X-OiDPRS call makeself.bat set RLMAKE_FLAGS=-X-OiDS call makeself.bat со включённым профилем время работы составило 1590 секунд, где-то 50 % времени ушло на проверку отношения Хигмана-Крускала. В актуальной реализации время работы составило 575 секунд, отношение Хигмана-Крускала занимает где-то около процента. Подробности с логами профилировщика в issue.
Рекомендуется смотреть коммит с игнорированием пробельных символов.
Эта правка была закоммичена в предыдущем коммите по ошибке.
Ранее при построении дерева прогонки, из сужений для ветвей извлекались имена используемых переменных. Теперь эти имена возвращаются функцией Solve-Drive. На быстродействие это почти не повлияло. Ранее: ExtractVariables-Expr (0000) -> 11519.0 ms (2.64 %, += 21.06 %) rel step time 0.67 ExtractVariables-Expr (0000) -> 13593437 (3.92 %, += 8.41 %) rel step time 0.67 Теперь: ExtractVariables-Expr (0000) -> 11687.0 ms (2.73 %, += 21.22 %) rel step time 0.71 ExtractVariables-Expr (0000) -> 13442507 (3.87 %, += 8.34 %) rel step time 0.71 Число шагов уменьшилось на 0,05 % (3,92−3,87), а доля времени даже выросла.
Данная правка на время и число шагов функции SimplifyCoordinates-Expr, вопреки ожиданиям, никак не повлияла. Ранее: Total time: 427.50000 s SimplifyCoordinates-Expr (3646) -> 6957.0 ms (1.63 %, += 26.16 %) rel step time 0.90 SimplifyCoordinates-Expr (3646) -> 6259417 (1.80 %, += 24.36 %) rel step time 0.90 SimplifyCoordinates-Expr-Inner (3646) -> 6274.0 ms (1.47 %, += 29.18 %) rel step time 1.17 SimplifyCoordinates-Expr-Inner (3646) -> 4372638 (1.26 %, += 30.18 %) rel step time 1.17 Сейчас: Total time: 422.06200 s SimplifyCoordinates-Expr (5246) -> 6909.0 ms (1.64 %, += 28.27 %) rel step time 0.90 SimplifyCoordinates-Expr (5246) -> 6222848 (1.81 %, += 24.66 %) rel step time 0.90 Число шагов SimplifyCoordinates-Expr даже, почему-то, возросло. Но SimplifyCoordinates-Expr-Inner больше нет, программа ускорилась на сэкономленные ≈6 секунд. Понятно, что это однократный замер, просто интересно совпало.
В коммите 286a098 классификация была неточная, но к ошибкам это не приводило.
#359) Файл OptTree-Drive-Expr.ref переименован для сохранения истории правок.
Содержимое лога для теста bloat-basic.ref (приложенного к заявке) не изменилось за исключением вывода самой истории. Т.е. на данный тест замена никак не повлияла. На других примерах работу не испытывал.
Фактически, развёрнут последний виток цикла.
• Удалено промежуточное звено SpecCall-BuildSignature-***, • функция SpecCall-CheckSignature выпала из цепочки и стала нерекурсивной (избыточные параметры удалены).
Экземпляры строятся как обычно, но при обнаружении зацикливания более ранний экземпляр в истории также подменяется вызовом обобщённого вроде Loop@3 { (e.0) t.1 t.2 e.3 = <Loop@8 (e.0) t.1 W S t.2 e.3>; }
Перемена нумерации позволяет тривиальным сигнатурам на дне истории (сигнатурам псевдоэкземпляров Func@0) выглядеть в логеконсистентно с последующими сигнатурамии Func@n, где нумерация начинается с 0.
Два автотеста недописаны (нет функции Go) и поэтому выключены (переименованы в *._ref). Случайно сгенерированный автотест, заваливший CI, сохранён и на нём компилятор по-прежнему падает. Смысл коммита — не потерять эти тесты. Когда проблема #362 будет исправлена, тесты opt-tree-bloat-*._ref будут дописаны и включены.
Для специализации это очевидный рефакторинг, т.к. разметка выполняется не более чем один раз в любом режиме компиляции. (Вообще, этот код давно надо было упростить.) Для прогонки это не рефакторинг, т.к. при прогонке экземпляров содержимое лога будет немного другим. Помимо непосредственного удаления кода «обновления» структур данных, были сделаны некоторые простые рефакторинги в окружающем коде.
Ранее было обнаружено, что с новым алгоритмом специализации компилятор в некоторых тестах увязает, и был добавлен грязный хак, ограничивающий максимальное число экземпляров (54c28ca, #332). Предыдущие два коммита стали строить дополнительные let-экземпляры, из-за чего порог стал достигаться раньше и глубина оптимизации снизилась. Поэтому потребовалось поднять порог. Порог был поднят до 150 по двум причинам: • В тесте saved-test-10_Mon-Aug-23-21-51-16-UTC-2021.ref (81667ba) на пороге в 100 экземпляров условие остановки не срабатывает (до let-экземпляров срабатывало). Опытным путём было выяснено, что условие установки срабатывает на пороге между 140 и 145, было выбрано круглое значение. Заметим, что этот тест в текущем коммите проходит. • Тест saved-test-77_14.08.2021_20-00-01,67-big.ref (41ce59e, #314), напротив, проходит только благодаря наличию этого лимита (на момент написания коммита 41ce59e не анализировалась проблема с непрохождением теста, просто был повышен порог). С лимитом 200 тест не проходит, с лимитом 150 проходит.
Конкретная проблема предыдущего коммита была в том, что на вход финальной прогонки экземпляров подавалось дерево с функцией Func*n, но при этом функция Func в дереве могла отсутствовать. Для прогонщика это было нарушением инварианта. Исправление свелось к тому, что Func*n уже больше не подлежат финальной прогонке, т.к. подлежат только экземпляры — функции с другим суффиксом @n. Была и другая проблема (не проявлялась). Она была в том, что ранее на финальном этапе выполнялась разметка всех функций для прогонки, а функции с именами вида Func*n прогонялись уже не адекватно, т.к. предложения в них уже могли быть размножены, и прогонка одного предложения приводила бы к неправильной функции Func*‹n+1›.
Обнаружилась проблема, связанная с исчерпанием числа шагов на тесте varcopy-fail.ref. Я предположил, что проблема в лишних let-экземплярах, которые съедают один шаг. Поэтому всё-таки реализовал #230 в рамках исправления #362. Как оказалось, реализовать поддержку активных вызовов оказалось проще, чем я думал ранее.
Проблему прекрасно описывает обширный комментарий в коде. Тест varcopy-fail.ref переименован, т.к. он выявлял проблему, решённую в коде.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Совершенству нет предела. Скоро новый релиз?
Когда появится коммит, меняющий этот файл. Но вообще, в конце комментария #362 (comment) поставлен вопрос, на который я бы хотел сначала ответить. Самому интересно, на сколько актуален сейчас этот проход. А так да, совершенству нет предела. |
Предыдущий коммит d5847ba устранял падение компилятора, скрывая ошибку: оптимизация просто переставала работать.
После вливания правок по #341 в FindErrors в Checker.ref увеличилась потребность в памяти — дерево e.AST теперь копируется: <CheckScreening (e.WarningIds) (e.AST)> <CheckMultiScreening (e.WarningIds) (e.AST)>; Поэтому пришлось повысить лимит для компиляции Library.ref в соответствующей папке.
В версию 3.4 войдут, прежде всего расширенные прогонка и специализация, написанные @Apakhov’ым и @VladisP’ом, этот код уже в
master
.Данный pull request вливает:
-OiADPRS
).