← All posts tagged Lua

Переписал компилятор и RTS так чтобы в качестве infotable'ов использовались метатаблицы лунного. Теперь, используя debug.setmetatable, можно представлять функции в виде... функций (а не в виде таблицы со амилками на infotable и функцию). Использование этого хака позволяет генерировать код выполняющийся на 9-11% быстрее. Не плохо наверное, но я ждал больше. Давно хочу примерно также хакнуть и алгебраические типы (что для арифметики даст что-то вроде тотального анбоксинга), но без объявления ADT'ов такое не провернуть, а в stg её нет.

Расскажу небольшой анекдот перед отъездом. Решил я от отчаяния уменьшить в нескольких тестах число обновляемых замыканий. Уменьшил. Время выполнения выросло, а число заходов в замыкания — нет. Оказалось что санком быть выгоднее чем протсо функцией без аргументов: при заходе в функцию вычитывается её арность из памяти, выделяется память под аргументы, которые снимаются со стека аргументов, создаются итераторы чтобы перебирать элементы на стеке. А санку достаточно запихнуть свой адрес в апдейт-фрейм и вычислить своё тело. Смешно вышло.

Запилил совместимость выхлопа компилятора с luajit. На тестах где создаётся много санков и тормозов luajit показал в 3 — 4 раза лучшее время выполнения чем просто lua. Ожидаемо. При этом lua использует процентов на 5% больше памяти в пике чем luajit. Странно.

Я очень грустил и плевался, когда приходилось из кусочков дерева language-lua собирать реальную программу. Хе. Это была ерунда по сравнению с тем чтобы его обходить. Возня с AST'ом моего Stg описанным почти целиком одним типом оказалась совсем тривиальной. Интересно, цивилизация придумала что-нибудь для обхода деревьев с большим количеством конструкторов и состоящих из нескольких типов.

Я понял как я ломаю стек лунного: при вычислении длины списка у меня накапливаются ленивые суммирования, которые как я не крути всё равно представляют цепочку не хвостовых вызовов. Когда этих отложенных суммирований набирается 50 — 100 тысяч, а потом внешнее резко форсируется происходит несколько десятков тысяч нерекурсивных вызовов функции рантайма EVAL (вычисляющей отложенное значение и раскручивающей продолжения) и стеку лунного становится плохо. Не знаю как это чинить. Была бы это сишка, можно было бы сделать переход в EVAL в виде jump'а…

А в лунном кэш на слабых ссылках не имеет тех же проблем что и в Java/Haskell? Вроде бы там основная проблема это поколения, которых нет в lua. Кстати, на кой дьявол в управляемых языках слабые ссылки? Вроде бы в этом был смысл когда мусор собирался подсчётом ссылок и программисты старались не создавать циклических структур. А сейчас-то зачем?

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

В тему #2717879. Переписал рантайм-систему с учётом специфики lua и починил апдейты. Длину списка в 10 ^ 4 элементов удалось посчитать за пол секунды. На 10 ^ 5 переполнился стек. Интересно где.

Моя лунная stg-машина считала длинну сгенерированного списка пропущенного через map четыре минуты времени. В списке было 10 ^ 4 элементов. Мусорщик лунного успешно удерживал объём кучи на 40 мегабайтах. Это так мило. Впрочем у меня нахрен сломаны апдейты графа, так что может быть не всё так плохо.

Кажется понял зачем нужен алгебраический тип вокруг встроеннных типов: встроенные типы unboxed и в общем случае хранить в алгебраическом типе вместо значения указатель на вычисление затруднительно. Таким образом, обёртка вокруг встроеннного типа и правда единственный способ дать ему побыть частью ленивого вычисления. Остался только один нюанс: что в терминах lua является unboxed значением?

Моя лунная stg-машина посчитала факториал! Поскольку парсер грамматики stg я написал удивительно трансректальным образом, а сам транслятор никак не проверяет корректность AST-дерева перед переписыванием в луну, факториал видимо останется самой сложной программой которую я смог для него написать.

Lua

Интересное кино. В lua таблицы передаются по ссылке. При этом переписать из функции таблицу переданную как аргумент у меня не получается, а захваченную как замыкание — запросто. Любопытно зачем это надо.