Лисп в изгнании
229 subscribers
156 photos
21 videos
5 files
233 links
Авторский канал на околоайтишную тематику.

По всем вопросам @awkravchuk
Download Telegram
#common_lisp #лытдыбр

Путём длительных экспериментов выяснил, что из всех дистрибутивов GNU-тый CLISP собран с поддержкой тредов, а, следовательно, и с возможностью загрузки bordeaux-threads, только в NixOS и в Gentoo (да и то, если в последней включить юз-флаг threads). Возможно, в Guix тоже, но только после того, как там примут патч от моего подписчика. Но в NixOS настолько древняя версия, что на неё даже Quicklisp не ставится. В общем, в порыве очередной оптимизации CI для своего ECS-фреймворка я всё перелопатил, и теперь в нём CLISP запускается из аж специального докер-образа 😅
🔥5
#видео #лытдыбр

Посмотрел тут выступление крутейшего Майка Актона, одного из популяризаторов идей data-oriented programming (и ECS в частности). В докладе Майк, как водится, гнёт линию, что не нужно заниматься генерализацией и пытаться решить какие-то эфемерные общие случаи, а нужно решать те задачи, которые конкретно есть в руках в данный момент. Мысль о том, что всё течёт, всё меняется, не бывает на самом деле "future-proof" кода и уже через пять-десять лет код твоей игры (да и сама игра), скорее всего, никому не будет нужен, довольно болезненная, но глубокая 🤔
5
#лытдыбр

В принципе, начинаю понимать г-на Влада Цепеша, жившего в своё время в краях по соседству, потому что в таком климате единственный способ выжить без кондиционера — это, действительно, дрыхнуть днём в каком-нибудь тёмном подземелье с приятным могильным холодком, и только с заходом солнца выползать из него поделать дела 🫠
🔥7🤗1
#лытдыбр #common_lisp

Вообще я думал, что неплохо соображаю в классических структурах данных, но если начинаешь заниматься низкоуровневой оптимизацией с расчёсыванием кэша CPU вдоль шёрстки и вот этим вот всем, становится жарковато. В последние дней десять занимался тем, что добавлял в свой ECS-фреймворк индекс, прямо как в реляционных БД — вспомогательную структуру данных, которая позволяет быстро сделать обратный запрос, т.е. ответить на вопрос "какие сущности имеют вот это конкретное значение такого-то слота такого-то компонента?". Так вот, следите за руками:

• Хэш-таблица с цепочками в виде лисповских односвязных списков замечательно подходит, но любой поиск по такому индексу — это ужас с точки зрения кэша процессора, да и при вставке требует лишних аллокаций.
• Хэш-таблица с открытой адресацией прекрасно уложится в кэш, так как является по сути единственным плоским массивом, но малину портит тот факт, что сущности с одинаковыми значениями слота в неё вставляются чёрти как, а для кэша хорошо бы было, чтобы они шли в аккуратном возрастающем порядке; а организовать какой-нибудь бинарный поиск места для вставки не выйдет потому, что несколько probing sequences (как это по-русски, последовательности попыток?) могут пересекаться.
• Сбалансированное бинарное дерево тоже подошло бы, если бы не случай одинаковых значений слота — за логарифмическое время, мне кажется, никак не получить все сущности с одинаковыми значениями, придётся обходить вообще всё дерево за O(n), и зачем тогда вообще такой индекс нужен.
• На B+-дерево что-то боюсь замахнуться 😅

Судя по тишине в моём вопросе на SO никто индексами в ECS особо не заморачивался.
В общем, если формализовать задачу, нужна структура данных, в которую можно сравнительно быстро, хотя бы за логарифм, вставлять повторяющиеся ключи произвольного типа (значения слота компонента) со связанными с ними целочисленными значениями (сущностями) и быстро, в идеале за константное время, получать в отсортированном виде все значения, связанные с заданным ключом. Ну и в идеале чтобы эта структура не превращала кэш CPU в щепки 😂

P.S. Перечитал пост и понял, что действительно из того, что я знаю, подходит либо B+-дерево, либо хэштабличка с отсортированными цепочками. Скорее всего, на завтрашнем стриме буду делать второй вариант, хотя B+ тоже интересно, раньше никогда руками такого не делал.
🔥8👍2
#лытдыбр #common_lisp

На этой неделе решил взяться за behaviour trees — паттерн, используемый для построения сценариев функционирования NPC в играх, и заодно попытаться натянуть его на паттерн ECS 😅 Даже изобразил простенькое тестовое дерево для персонажа-вражины, пытающегося догнать игрока и пнуть его в ближнем бою (см. рис. 1). Правда, с первого раза реализовать не получилось, — мозг запнулся о тот факт, что возвращаемое из узлов дерева булевское значение (успех/неуспех) нужно хранить для каждого узла дерева, а не по одному на всего персонажа, что неизбежно приводит к тому, что своя копия дерева должна быть у каждого персонажа; а мне изначально хотелось сэкономить памяти и хранить только один экземпляр дерева на всех. В общем, завтра с утра на стриме попытаюсь переделать ровно 😊
🔥3
#лытдыбр

Решил на пару недель сделать перерыв от стриминга, чтобы уже домучать серию туториалов по своему ECS-фреймворку, тем более что я календарь перевернул и снова дофига занятий, которые нужно вести по работе. Заодно по ходу дела надо будет что-то уже решить с поддержкой MacOS и своей дистрибуцией Quicklisp со свежими версиями фреймворка.

Первая часть туториала уже готова где-то на две трети, так что, думаю, в ближайшее время будет. Как говорится, оставайтесь тунцом 😋
6👍2
#мемасики

Дзен-буддизм, который мы заслужили 😂
#мемасики

В лиспочатике тут прекрасное запостили)
6😁4👍1
#common_lisp #лытдыбр #проекты

На этой неделе на утренних стримах решил переключиться на GUI-шную библиотеку Nuklear, она (а точнее мои биндинги к ней) давно требует любви ❤️
Уже успел пофиксить всякие мелочи и добавить парочку клёвых макросов в её DSL, а сейчас вот закодил вот такую реализацию assert для неё — надоело, что если хоть что-то с ней делаешь не так, она тут же вызывает сишный ассерт, что приводит к тому, что SBCL вываливается в LLDB (низкоуровневый отладчик), а в Emacs'овских Sly/Slime этого не видно, и кажется, что просто "всё зависло". Теперь хоть будет видно, что произошло, всяко дружелюбнее к пользователю 😊
👍2
#лытдыбр #common_lisp

Стою перед сложным выбором, в какую сторону начать бухтеть:
• Экзотической ОС Ш1ИДОШ5;
• Мейнтейнеров MSYS, которые даже не берут на себя труд запустить тот софт, который они распространяют;
• Г-на Фукамачи, который пишет код так, как будто его никто не видит.

Прямо дилемма 🤔
😁5🤔1
#common_lisp #лытдыбр

Есть у меня в гуёвой библиотеке cl-liballegro-nuklear макрос, with-style-item, который вызывает сишную функцию nk_style_push_style_item, которая, в свою очередь, принимает на вход среди всего прочего два указателя, на "контекст" (по сути точка входа в сишную библиотеку, структура, в которой хранится вся нужная инфа о текущем состоянии GUI), и указатель на ту деталь стиля оформления, которая меняется внутри этой структуры, по сути тот же первый указатель, но со (сравнительно) небольшим оффсетом. Так вот, как выяснилось по итогам экспериментов и треда на реддите, SBCL не умеет аллоцировать свои обёртки для сишных указателей на стеке. От слова "совсем". Наглядная демонстрация:

> (macroexpand-1 '(nk:with-style-item c nk:+style-window-fixed-background+
(nk::style-item-image* i)))
(LET ((#:ITEM353 (CL-LIBALLEGRO-NUKLEAR:STYLE-ITEM-IMAGE* I))
(#:OFFSET354
(CFFI-SYS:INC-POINTER C
CL-LIBALLEGRO-NUKLEAR:+STYLE-WINDOW-FIXED-BACKGROUND+)))
(DECLARE (DYNAMIC-EXTENT #:ITEM353 #:OFFSET354))
(CL-LIBALLEGRO-NUKLEAR:STYLE-PUSH-STYLE-ITEM C #:OFFSET354 #:ITEM353)
(CL-LIBALLEGRO-NUKLEAR:STYLE-POP-STYLE-ITEM C))


> (disassemble #'(lambda (c i)
(declare (type cffi:foreign-pointer c i)
(optimize (speed 3) (safety 0) (debug 0)))
(nk:with-style-item c nk:+style-window-fixed-background+
(nk::style-item-image* i))
nil))
; ... snip ...
; full: https://gist.github.com/lockie/24fa8c730eb82f53e7e79db418a71b8b
; 343: L2: 6A10 PUSH 16
; 345: FF142578050050 CALL [#x50000578] ; #x52A004F0: ALLOC-TRAMP
; 34C: 5F POP RDI
; 34D: 4080CF0F OR DIL, 15
; 351: EB9A JMP L0


Обратите внимание, как SBCL упорно ложит с прибором на декларацию dynamic-extent и выделяет под CFFI-ный указатель 16 байт (видимо, сам указатель и тэг типа) с кучи. Чтобы такое зафиксить, придётся лезть глубоко в кишки SBCL и перетирать с его разработчиками, а мне чёт неловко таких серьёзных людей от их дел отвлекать 😅
#лытдыбр #common_lisp

Сегодня закончил с оптимизацией функции поиска пути персонажа по алгоритму A* — теперь уже ни в самой функции, ни в её окрестностях улучшать в плане производительности нечего, всё вылизано до блеска. В итоге путь в сложном лабиринте с большим количеством длинных коридоров и поворотов на 180° со скриншота находится чуть меньше, чем за половину миллисекунды. Это, наверное, не очень впечатляющий результат для какой-нибудь RTS, но в столь специфичном жанре нужны будут свои хаки вроде кэширования путей или предварительного вычисления графа с компонентами связности для карты и запуска A* на нём. Если сравнивать с моим кринжовым опытом реализации A* на лиспах четырёхлетней давности, который глючный, дёрганый и тормозной, сейчас получился прямо огонь 🔥
🔥9
#мемасики

Мы или не мы?
😁1😢1
#статьи

Опубликовал на хабре перевод статьи о том, как Lisp в космос летал. В целом от этой истории вайб, конечно, максимально похож на вот этот кадр
10
#лытдыбр

Опа, приплыли. Подкрался незаметно, хоть виден был издалека.
Надо Nyxt расчехлять. Ну или там Qutebrowser накрайняк.
💩1
#проекты #лытдыбр

Делаю финальную вычитку первой части руководства по своему микрофреймворку cl-fast-ecs, и опять наталкиваюсь на плохие новости — какой-то долбоёб выкупил домен liballeg точка org и снёс оттуда сайт либы liballegro, которую я использую в каждом первом своём проекте. Это ж в скольких местах теперь придётся ссылку менять на нормальную 😩
😢4
#лытдыбр #common_lisp

Наконец опубликовал первую часть туториала по ECS-фреймворку cl-fast-ecs: https://habr.com/ru/articles/767342 , вы знаете, куда насыпать апвоутов 😊

Он у меня занял на порядок больше времени и сил, чем я планировал, наконец можно немношк выдохнуть
🔥9
#лытдыбр

В эту пасмурную, дождливую и вялую субботу itch.io даёт повод улыбнуться 😊🫖
🤔2
This media is not supported in your browser
VIEW IN TELEGRAM
#лытдыбр #проекты #common_lisp

Итак, в рамках идущего уже третий день Autumn Lisp Game Jam 2023 я наконец добил простейшее дерево поведения для персонажа вида "выбрать любого другого персонажа в области видимости, подбежать к нему и сделать ближнебойный BOINK".
Но мне не нравится то, что я написал 😅 Сами узлы дерева в рамках модели ECS у меня сейчас хранится неоптимально, приводя к большому количеству промахов по кэшу, поэтому настало время переписывать весь код, код сам себя не перепишет 😂
🎄5💯1