-
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
Ускорение работы оптимизатора прогонки #239
Comments
Результаты профилированияВыполнил замер при помощи профилировщика #246. Самоприменение неоптимизированной версии без оптимизации, первые 14 функций по времени (50 % времени выполнения программы, время в мс): makeself.bat без оптимизации
Видно, что только две функции требуют более 5 % времени ( А вот замер для запуска неоптимизированной версии с ключами set SRMAKE_FLAGS=-X-ODS -X--opt-tree-cycles=10 (запускаем неоптимизированную версию, поскольку в оптимизированной будут всякие
При этом общий профиль программы такой:
На первой строчке находится refal-5-lambda/src/srlib/common/LibraryEx.refi Lines 73 to 80 in f4e56e6
Без оптимизации refal-5-lambda/src/compiler/OptTree-Drive.ref Lines 534 to 539 in f4e56e6
Здесь на каждой итерации копируется Если проанализировать остальные медленные функции, то тоже выяснится, что на каждой итерации там происходит копирование
Последующие строчки ( Что делать?Очевидное (и кошерное) решение состоит в том, чтобы переписать перечисленные выше функции так, чтобы они не копировали Но это достаточно сложный и долгий рефакторинг. Рефакторинг делать надо, но не сейчас. Есть другое предложение: снизить стоимость копирования. Наиболее тяжёлое в Предлагается тела функций в В Рефале-5λ есть такой вид ссылок — это безымянные функции, замыкающие контекст. Функция вида Поэтому предлагается хранить тела функций в |
Завернул тела функций в замыкания. Результат обрадовал (условия запуска те же):
Ускорение составило 872,687/277,422 = 3,1457 раз! При этом уменьшились метрики Однако, по-прежнему лидируют Так что надо оптимизировать первые две функции, передавая данные оптимизаций через аккумулятор. |
Таблица t.DriveInfo теперь не копируется, а передаётся через аккумулятор
С оптимизацией
Не смотря на отсутствие копирования Но, тем не менее, имеем ускорение 277,422/170,343 = 1,6286. По сравнению с исходным: 872,687/170,343 = 5,1231. И это только тактическая оптимизация. Стратегическая оптимизация будет заключаться в рефакторинге и переработке подхода. Возможный рефакторинг: в функцию Отдельно оптимизировать |
Ускорение в 5 раз, конечно, внушительно. Но всё равно это медленно. На выполнение самоприменения с ключами set SRMAKE_FLAGS=-X-ODPRS требуется около получаса времени (причём это повторный прогон оптимизированной версии):
Так что нужно реализовывать стратегическую оптимизацию. |
Запуск set SRMAKE_FLAGS=-X-ODS -X--opt-tree-cycles=10 print-statistics = true
enable-profiler = true Результаты:
Последующий запуск с ключами set SRMAKE_FLAGS=-X-ODPRS print-statistics = true
enable-profiler = false Результат:
(т.е. 23 минуты 6 секунд) И ещё один запуск оптимизированной версии:
(20 минут 28 секунд) Применим несколько коммитов с побочными багфиксами, рефакторингами и тактическими оптимизациями. |
Отчасти этот коммит является и оптимизацией, поэтому ссылка на #239
Теперь при подстановке сужений проверяется содержимое замороженных скобок: если оно изменилось, скобка оттаивает, иначе остаётся как есть. Ранее подогрев включался в зависимости от контекста подстановки, и включался неправильно, из-за чего достигалась недостаточная глубина оптимизации.
Часть кода ответственного за прогонку и встраивание, была очень похожа с точностью до копипаста. Данный код был рефакторизован в исходном смысле слова «факторизация» — написана одна функция, параметризуемая ключом «прогонка/встраивание». Ну и мелкие попутные правки.
Коммиты выше исключительно тактические. Повторим замеры из предыдущего комментария. set SRMAKE_FLAGS=-X-ODS -X--opt-tree-cycles=10 print-statistics = true
enable-profiler = true
Ускорение в 142/108 = 1,3 раза.
set SRMAKE_FLAGS=-X-ODPRS print-statistics = true
enable-profiler = false
(13 минут 25 секунд, ускорение 1386/805 = 1,7 раз)
(11 минут 46 секунд, ускорение 1228/706 = 1,7 раз) И это только тактические оптимизации. Пришёл черёд стратегической. |
Стратегическая оптимизация сделана! Замеры: set SRMAKE_FLAGS=-X-ODS -X--opt-tree-cycles=10 print-statistics = true
enable-profiler = true
Ускорение в 108/79,9 = 1,3 раза.
set SRMAKE_FLAGS=-X-ODPRS print-statistics = true
enable-profiler = false
(2 минуты 55 секунд, ускорение в 805/174,9 = 4,6 раз)
(2 минуты 13 секунд, ускорение в 706/133 = 5,3 раз) |
ВыводРезультаты показывают приемлемую скорость компилятора. Т.е. компилятор можно самоприменять с ключами максимальной оптимизации |
Оптимизатор-прогонщик работает очень медленно, особенно медленно совместно с режимом специализации, с которым и должен совместно работать. Вот таблица:
-OT
-OD
-OS
-ODS
Замеры неточные, но порядок величины отражают достоверно. Кроме того, лютую долю времени при прогонке занимают копирования t- и e-переменных и контекста, например, в последнем замере они требуют, соответственно, 79,0 % и 15,8 %.
Понятно, что в случае
-ODS
фронт деятельности прогонщика расширяется: появляется возможность оптимизировать вызовыApply
в функцияхMap@n
, а затем и прогнать там замыкания.Поэтому предлагаются следующие пути для оптимизации:
Func*n
(Удалять и не порождать неиспользуемые функции #228). Оно приводит к наполнению дерева ненужными функциями видаFunc*n
, которые никогда не вызываются. Из-за этого каждая следующая итерация выполняется дольше, временна́я сложность возрастает на лишний порядок. Это хорошо заметно на файлеGenerator-RASL.ref
, в котором прогоняется функцияNumberFromOpcode
, содержащая 119 предложений.Failure
), то вызов функцииFunc
заменяется наFunc*1
, вызовFunc*n
наFunc*(n+1)
. Следующий такой вызов будет анализироваться на следующей итерации. Предлагается за одну итерацию анализировать сразу несколько предложений. В этом случае бо́льшая глубина оптимизации будет достигаться за меньшее число итераций.The text was updated successfully, but these errors were encountered: