Мотивация
Мотивация простая — ускорение работы компилятора. На данный момент самоприменение самого компилятора (rlc-core) требует нескольких десятков секунд.
Другая мотивация — обеспечить для rl-refgo-wrapper (см. #334) более-менее приемлемое время работы.
Реализация
Фактически, это будет Ccache (https://ccache.dev/), встроенный в компилятор. Или некий аналог Zapcc (#177) — кэширующего компилятора C++ на основе Clang.
Компилятор должен принимать флаг --cache-dir=…, в котором указывается папка кэша .rasl’ов (и, возможно, .cpp-шек). Пустой параметр командной строки отключает кэш.
На данный момент на результат трансляции влияют помимо содержимого самого файла также флаги компиляции (-O… и --markup-context) и содержимое всех прямо или косвенно подключаемых включаемых файлов. Следовательно, все эти данные должны учитываться.
Кэширование планируется осуществлять по хэшу, вычисляться хэш должен будет от содержимого файла, включаемых файлов и используемых ключей компилятора. Предлагается использовать хеш-функцию Дженкинса lookup3, т.к. она уже реализована в компиляторе. Криптографической безопасности не требуется, достаточно минимизации коллизий. Хеш-функция даёт два 32-разрядных числа, что даёт шанс коллизии 1 на 4 миллиарда (атака дней рождения). Если компиляцию вызывать каждые 5 минут, на каждой перекомпиляции менять по 3 файла, то за рабочий день (8 часов) наберётся 12×3×8=288 файлов. За год 288×366 = (327 + 39)×(327 − 39) = 327² − 39² ≈ 320² − 40² = 102 400 − 1600 ≈ 100 000 файлов. За 10 лет — миллион, что много меньше 4 млрд. Коллизия невероятна.
После отказа от включаемых файлов (#318) хешировать потребуется прелюдию, опции и сам файл.
Предлагается дополнить модуль Hash функцией HashLittle2-File, которая принимает не строку character’ов, а имя файла — так она будет эффективнее.
Кэширование можно выполнять не на уровне rlc, а на уровне rlmake. Следует обдумать оба варианта.
Вычисление хэша должно выполняться до лексического анализа, что затрудняет поиск $INCLUDE. Можно поступить так, как это сделано в rlmake — распознавать $INCLUDE только в одиночных строчках. Но тогда возможны ошибки в обе стороны — ложноположительные ошибки, когда эта строка находится внутри многострочного комментария, ложноотрицательные, когда директива находится не в отдельной строке. Поэтому проще дождаться удаления $INCLUDE из компилятора (#318).
Мотивация
Мотивация простая — ускорение работы компилятора. На данный момент самоприменение самого компилятора (
rlc-core) требует нескольких десятков секунд.Другая мотивация — обеспечить для
rl-refgo-wrapper(см. #334) более-менее приемлемое время работы.Реализация
Фактически, это будет Ccache (https://ccache.dev/), встроенный в компилятор. Или некий аналог Zapcc (#177) — кэширующего компилятора C++ на основе Clang.
Компилятор должен принимать флаг
--cache-dir=…, в котором указывается папка кэша.rasl’ов (и, возможно,.cpp-шек). Пустой параметр командной строки отключает кэш.На данный момент на результат трансляции влияют помимо содержимого самого файла также флаги компиляции (
-O…и--markup-context) и содержимое всех прямо или косвенно подключаемых включаемых файлов. Следовательно, все эти данные должны учитываться.Кэширование планируется осуществлять по хэшу, вычисляться хэш должен будет от содержимого файла, включаемых файлов и используемых ключей компилятора. Предлагается использовать хеш-функцию Дженкинса
lookup3, т.к. она уже реализована в компиляторе. Криптографической безопасности не требуется, достаточно минимизации коллизий. Хеш-функция даёт два 32-разрядных числа, что даёт шанс коллизии 1 на 4 миллиарда (атака дней рождения). Если компиляцию вызывать каждые 5 минут, на каждой перекомпиляции менять по 3 файла, то за рабочий день (8 часов) наберётся 12×3×8=288 файлов. За год 288×366 = (327 + 39)×(327 − 39) = 327² − 39² ≈ 320² − 40² = 102 400 − 1600 ≈ 100 000 файлов. За 10 лет — миллион, что много меньше 4 млрд. Коллизия невероятна.После отказа от включаемых файлов (#318) хешировать потребуется прелюдию, опции и сам файл.
Предлагается дополнить модуль
HashфункциейHashLittle2-File, которая принимает не строку character’ов, а имя файла — так она будет эффективнее.Кэширование можно выполнять не на уровне
rlc, а на уровнеrlmake. Следует обдумать оба варианта.Вычисление хэша должно выполняться до лексического анализа, что затрудняет поиск
$INCLUDE. Можно поступить так, как это сделано вrlmake— распознавать$INCLUDEтолько в одиночных строчках. Но тогда возможны ошибки в обе стороны — ложноположительные ошибки, когда эта строка находится внутри многострочного комментария, ложноотрицательные, когда директива находится не в отдельной строке. Поэтому проще дождаться удаления$INCLUDEиз компилятора (#318).