текст программы имеет такую же структуру, как её AST, но что именно это значит?
То что интерпретатор лиспа на лиспе будет занимать строчек 20-30.
Может, найдете время написать статью для людей, которые не в теме компиляторов (но известно, что такое машина Тьюринга)?
Может быть %)
mSSA/aSSA
Memory SSA, Array SSA.
прувер на решетках
Рассматривается задача приведения термов в многомерном решётчатом пространстве к точке или хотя бы прямой/плоскости. Почитайте что-то про SAT/SMT-пруверы, да и polyhedral.info никто не отменял.
transactional-SSA
Разновидность SSA формы наподобие Rust'овского mIR'a (borrow checks) что бы расставлять блокировки (рассматривается просто STM модель, как в хаскеле и скале с mvar/tvar) при конкурентном доступе.
httpStatus от 200 до 600? Тип int(200, 600)?
Да int(200, 600) :D
Exception при парсинге сообщения?
Да, и автоматическое освобождение ресурсов через bracket-подобные примитивы (см scala cats-effect например, но есть и в котлине через Arrow и в Swift через bow).
И что показывают бенчимарки для одинаковой функциональности на вашем языке и на условном C++ / Lisp / C# / Elixir?
Статическое потребление памяти, задержки и нагрузку на процессор при максимальном трафике сервисов… Бэнчмарки нормальные могу гонять только на Power9/Power10 т.к. там для такого есть вменяемый набор инструкций. В целом от прирост около 30-400% в зависимости от задачи, и потребление памяти гораздо ниже 5-200% тоже в зависимости от задачи.
В основном сейчас язык использую для генерации HDL кода, портирую Power10 ISA.
Все эффекты лифтятся аргументами функции при вызовах… да и сам вызов функции рассматривается как "возникновение события" с timeout'ом и cancelation'ом — т.е. можно "отменить" каскадно при возникновении ошибок когда не совпадает range в runtime'e… под "побочкой" подразумевается гарантированная невозможность возникновения "непредвиденных" эффектов i.e. lifelock'ов / deadlock'ов / race condition'ов и т.д. и верификация именно во время компиляции. Можно представить как rust где не нужны Boxed Types, RefCells / Rc, Mutex'ы и ARC вообщe. Так как это решается системой типов.
Наличие диапазонов принимаемых значений также позволяет значительно упростить модель памяти и сделать её абсолютно детерминированной на этапе компиляции.
Используется система типов посложнее чем обычно… зависимые типы хранят в себе ещё и диапазоны, или зависимые функции диапазонов принимаемых значений.
query вы генерируете к пруверу?
Пруверы на решётках в общем… точка в решётке — диапазон значений строгий/не строгий или функция диапазона. Прувер должен доказывать что решётки не перескутся между собой и исследовать соответствующие зависимые функции диапазонов. Потом поверх этого есть ещё пару проходов полиэдральных трансформаций для реализации свёрток типов.
и отсутствие сайд-эффектов следует из well-typedness
Сама система типов реализует referential transparency т.к. есть transactional-SSA проекция с mem-SSA. Само блокировки/ожидания короч может расставить, выбрать где лучше скопировать, а где лучше указатель… и как потом Сompare-and-Swap делать etc. Много разных задач решается.
И я бы посмотрел на полноценные завтипы (а не как в ATS) для императивного языка
О них и речь… и это довольно комплексная проблема.
Если очень поверхностно, и если не вникать в логику (Constrainted Bunch/Separation logic и прочие расширения логики Хоара если точно), то получается что интерпретацию программ в автоматах Тьюринга надо рассматривать как "многоленточный" автомат — с командами переменной длинны и данными переменной длинны, когда длинна данных зависит от результата выполнения предыдущих команд, а длинна команд от позиций соседних лент.
Так в языке
Не должно быть макросов и прочей кодогенерации, т.к. вся информация о зависимых типах должна быть доступна на этапе компиляции. Вся рефлексия должна быть выполнима на этапе компиляции. Generic'и в топку...
Не должно быть линковки в привычном её понимании — JIT/AOT должен уметь пересобрать с PGO любой отпрофилированный код и выбрать наилучшую реализацию по существующему профилю.
Язык должен быть гомоиконным и строго типизированным (типизированные Lisp'ы 98го года и Shift, например), желательно что бы легко приводился к каноническим минимальным mSSA/aSSA формам без дополнительных трансформаций и свёртки.
Во время компиляции должны быть доступны диапазоны всех принимаемых переменной значений, например http статус от 200 до 600 и т.п., что бы компилятор мог выбрать конкретную размерность типа в зависимости от архитектуры и использовать соответствующий набор команд. Наличие диапазонов очень упрощает обработку ошибок и освобождение/планировку соответствующих ресурсов (сокеты, файлы и прочее).
Желательно использовать зависимые типы для формальной верификации и доказывать прувером отсутствие побочки на всех диапазонах принимаемых значений.
Если вникнуть — есть острый недостаток в SSA формах и их проекциях (array SSA, mem SSA) для решения задач Data-Computational Locality Projection. Для этого приходится часть логики работы с mSSA/aSSA/tSSA выносить на фронт LLVM'a, и плодить mir/mlir'ы, как это было с тем же Rust'ом, и как теперь будет с СLang'ом ...
Есть проблемы с типизацией в самих языках программирования — уже лет 10 изучаю этот вопрос, и пришёл в выводу что языки надо дизайнить что бы не создавали сложностей трансляции, правда по синтаксису получается лиспо-образное веселье с привкусом питонщины и эрланга.
В статье про Optimization Pass'ы ни слова про SSA / mSSA / Array-SSA, зато куча байт-кода…
Слишком глубоко копнули без разъяснения теоретических основ, общих оптимизационных задач и практик.
Там не умеют Overhead'ы мерить в принципе…
Даже банальный встраиваемый ehcache с offheap'ом был бы быстрее Redis.
Вот в Terracotta / Hazelcast было пару багов с RMI так что их пока не стоит рассматривать.
Не знаю, мне, лично, после DPDK/SPDK видеть 1.5K RPS довольно прискорбно, так как даже на PHP7 можно в ~10К+ RPS.
Оторвано от контеста.
В случае с тем же JS'ом — есть lerna, хочешь монорепку — делай моно, хочешь полирепку — делай поли через git submodules. Погоды особо не делает.
В разных языках — разные пакетные менеджеры, и очень мало жизнеспособного инструментария для монорепок.
там упрёшься в алгоритмы и структуры данных (диск/cpu/память) раньше чем в IO
Я думаю мне не стоит это комментировать, но действительно, многих и масштабирование простоя железа устраивает, и сопутствующий ClusterFuck тоже вроде как норм… слишком много притворства и невежества, к жизнеспособности решений отношения особо не имеет. Это как шутка про профилирования питона в Uber'e...
В суровом продакшен энтерпрайзе до асинхронщины-то с epoll часто не доходит
Обычно уже решено на уровне каких-то netty/jetty/uvloop/libev etc.
Оверхед сейчас в основном в persistence/network layer'aх, OverlayFS до сих пор радует, надо менять на что-то DPDK/SPDK совместимое, иначе этот весь лощёный Highload не более чем масштабирование простоя процессора. В целом, наличие Control Group'ы и соответствующих namespace'ов тоже даёт overhead, он почти такой-же как и от KVM'a сейчас...
Вряд ли они используют sriov для выполнения DPDK драйверов… С SPDK ситуация сейчас посложнее и готового решения для blobfs нету, ContainerD пока не поддерживает pluggable storage.
Лучшим примером DPDK приложения сейчас можно назвать ScyllaDB, по сравнению с ней все местные поделки на golang'e по 200К RPS выглядят довольно блекло.
Не особо помогают пофиксить эстимейты — Time-saving bias и прочее имеют совершенно иную природу чем вообще принято думать. Там обычно линейные эстимейты превращаются в экспоненциальные, а так как человеческий мозг осознать экспоненциальные зависимости не в состоянии — возникает искажение.
Когнитивное искажение формируется чаще всего из-за определённой внутренней компенсаторной потребности: "больно думать" / "больно признать" / "приятно думать" / "приятно думать только о приятном" etc
Чаще всего, в разработке, это Гало-эффект. Возникает при объектных отношениях (не люблю Кляйн), может быть применим не только к людям, но и к инструментарию.
поскольку люди часто цепляются ко всякой мелочи, которая даже не важна в разговоре
Переход от Blame Culture к Compassion Culture не решён — все коллективы успешно невротизированы, ведомы страхом и подчинением, с эмоциональной и вербальной депривацией. Subordinate Satisfaction даже у Google сейчас около 17%, и это считается нормальным повсеместно в Штатах.
Blame на русский прямо не переводиться и состоит из Accusation, Criticism, Punishment и Humiliation. Как раз то что принято у англоговорящих называть токсичным поведением.
когда при этом другие злорадствуют — это очень неприятно
Коллективов нет — есть стада и племена, с стандартными племенными "обычиями" и "ритуалами". Задачи достигнуть поставленной цели общими целями нет в принципе, потому что отношение к работе "мы — не продукт", "мы — не компания", "З/П платят — вот и чудно".
От бабушек едущих в забитом автобусе и орущих друг на друга — кому кто на ногу наступил, не особо отличается. Автобус поломается — подождут, и сядут на следующий, благо маршрут активный.
Такой же принцип используется в golang'e, только там ещё буфера (структуры) сортируются по частоте обращений — возможно будет полезно для вашего случая, так как там получается даже более чем в 10 раз быстрее.
Майнеры ликуют.
p.s. специально залогинился раз в 4 года что бы написать этот комментарий.
На самом деле, топовые ламповые устройства на рынке на много проще того что у вас выполнено.
Например вот та же Ейфория от Феликсa…
которая считается эталонной под топовые Бериливые и Планарные уши — Focal Utopia и Meze Empyrean.
Собрана на двух триодах 6SN7 и двух двойных триодах 6N13S для питания.
Имеет дискретный транзисторный Stage — это АB класс, и мало где об этом пишут.
Лампы там PsVane и вроде Electro Harmonics русские 6SN7, но не уверен...
Выглядит всё предельно просто
Единственное что конденсаторы дорогие, транзисторы подобраны вручную по номиналам, платы посеребрены, и везде используются серебряные проводники...
По схемотехнике вы наверное догнали, а может и перегнали, китайский Cayin HA-300.
Это 2 устройства на рынке с которыми можно сравнивать то что описано в статье.
Правда это усилители для наушников… в ламповом стационаре не разбираюсь.
Да и там вряд ли есть что-то интереснее того же Cayin M-845D.
Так что, в принципе, ВАШ труд на много сложнее и дороже топовых аудиофильских поделок...
То что интерпретатор лиспа на лиспе будет занимать строчек 20-30.
Может быть %)
Рассматривается задача приведения термов в многомерном решётчатом пространстве к точке или хотя бы прямой/плоскости. Почитайте что-то про SAT/SMT-пруверы, да и polyhedral.info никто не отменял.
Разновидность SSA формы наподобие Rust'овского mIR'a (borrow checks) что бы расставлять блокировки (рассматривается просто STM модель, как в хаскеле и скале с mvar/tvar) при конкурентном доступе.
Да int(200, 600) :D
Да, и автоматическое освобождение ресурсов через bracket-подобные примитивы (см scala cats-effect например, но есть и в котлине через Arrow и в Swift через bow).
Статическое потребление памяти, задержки и нагрузку на процессор при максимальном трафике сервисов… Бэнчмарки нормальные могу гонять только на Power9/Power10 т.к. там для такого есть вменяемый набор инструкций. В целом от прирост около 30-400% в зависимости от задачи, и потребление памяти гораздо ниже 5-200% тоже в зависимости от задачи.
В основном сейчас язык использую для генерации HDL кода, портирую Power10 ISA.
Зависит от породы… можно перешивать, хотя даже и рыбок можно… и тоже от породы и качества экземпляра зависит.
Все эффекты лифтятся аргументами функции при вызовах… да и сам вызов функции рассматривается как "возникновение события" с timeout'ом и cancelation'ом — т.е. можно "отменить" каскадно при возникновении ошибок когда не совпадает range в runtime'e… под "побочкой" подразумевается гарантированная невозможность возникновения "непредвиденных" эффектов i.e. lifelock'ов / deadlock'ов / race condition'ов и т.д. и верификация именно во время компиляции. Можно представить как rust где не нужны Boxed Types, RefCells / Rc, Mutex'ы и ARC вообщe. Так как это решается системой типов.
Наличие диапазонов принимаемых значений также позволяет значительно упростить модель памяти и сделать её абсолютно детерминированной на этапе компиляции.
p.s. у меня есть HDL таргеты...
Используется система типов посложнее чем обычно… зависимые типы хранят в себе ещё и диапазоны, или зависимые функции диапазонов принимаемых значений.
Пруверы на решётках в общем… точка в решётке — диапазон значений строгий/не строгий или функция диапазона. Прувер должен доказывать что решётки не перескутся между собой и исследовать соответствующие зависимые функции диапазонов. Потом поверх этого есть ещё пару проходов полиэдральных трансформаций для реализации свёрток типов.
Сама система типов реализует referential transparency т.к. есть transactional-SSA проекция с mem-SSA. Само блокировки/ожидания короч может расставить, выбрать где лучше скопировать, а где лучше указатель… и как потом Сompare-and-Swap делать etc. Много разных задач решается.
О них и речь… и это довольно комплексная проблема.
Скорее сам ЯП уже давно написан и решаются сугубо политические и бумажные вопросы.
Если очень поверхностно, и если не вникать в логику (Constrainted Bunch/Separation logic и прочие расширения логики Хоара если точно), то получается что интерпретацию программ в автоматах Тьюринга надо рассматривать как "многоленточный" автомат — с командами переменной длинны и данными переменной длинны, когда длинна данных зависит от результата выполнения предыдущих команд, а длинна команд от позиций соседних лент.
Так в языке
Если вникнуть — есть острый недостаток в SSA формах и их проекциях (array SSA, mem SSA) для решения задач Data-Computational Locality Projection. Для этого приходится часть логики работы с mSSA/aSSA/tSSA выносить на фронт LLVM'a, и плодить mir/mlir'ы, как это было с тем же Rust'ом, и как теперь будет с СLang'ом ...
Есть проблемы с типизацией в самих языках программирования — уже лет 10 изучаю этот вопрос, и пришёл в выводу что языки надо дизайнить что бы не создавали сложностей трансляции, правда по синтаксису получается лиспо-образное веселье с привкусом питонщины и эрланга.
Надо было бы о DSD упомянуть...
Без DPDK/SPDK смысла участвовать особо то нет...
В статье про Optimization Pass'ы ни слова про SSA / mSSA / Array-SSA, зато куча байт-кода…
Слишком глубоко копнули без разъяснения теоретических основ, общих оптимизационных задач и практик.
Там не умеют Overhead'ы мерить в принципе…
Даже банальный встраиваемый ehcache с offheap'ом был бы быстрее Redis.
Вот в Terracotta / Hazelcast было пару багов с RMI так что их пока не стоит рассматривать.
Не знаю, мне, лично, после DPDK/SPDK видеть 1.5K RPS довольно прискорбно, так как даже на PHP7 можно в ~10К+ RPS.
Оторвано от контеста.
В случае с тем же JS'ом — есть lerna, хочешь монорепку — делай моно, хочешь полирепку — делай поли через git submodules. Погоды особо не делает.
В разных языках — разные пакетные менеджеры, и очень мало жизнеспособного инструментария для монорепок.
На контейнерах 200-300К RPS потолок, на DPDK/SPDK 2-6M RPS потолок…
По этому подобные условия соревнований особо серьёзно не воспринимаю.
Я думаю мне не стоит это комментировать, но действительно, многих и масштабирование простоя железа устраивает, и сопутствующий ClusterFuck тоже вроде как норм… слишком много притворства и невежества, к жизнеспособности решений отношения особо не имеет. Это как шутка про профилирования питона в Uber'e...
Обычно уже решено на уровне каких-то netty/jetty/uvloop/libev etc.
Оверхед сейчас в основном в persistence/network layer'aх, OverlayFS до сих пор радует, надо менять на что-то DPDK/SPDK совместимое, иначе этот весь лощёный Highload не более чем масштабирование простоя процессора. В целом, наличие Control Group'ы и соответствующих namespace'ов тоже даёт overhead, он почти такой-же как и от KVM'a сейчас...
Вряд ли они используют sriov для выполнения DPDK драйверов… С SPDK ситуация сейчас посложнее и готового решения для blobfs нету, ContainerD пока не поддерживает pluggable storage.
Лучшим примером DPDK приложения сейчас можно назвать ScyllaDB, по сравнению с ней все местные поделки на golang'e по 200К RPS выглядят довольно блекло.
А можно без контейнеров, а то это совсем несерьёзный HighLoad получается ?
Не особо помогают пофиксить эстимейты — Time-saving bias и прочее имеют совершенно иную природу чем вообще принято думать. Там обычно линейные эстимейты превращаются в экспоненциальные, а так как человеческий мозг осознать экспоненциальные зависимости не в состоянии — возникает искажение.
Когнитивное искажение формируется чаще всего из-за определённой внутренней компенсаторной потребности: "больно думать" / "больно признать" / "приятно думать" / "приятно думать только о приятном" etc
Чаще всего, в разработке, это Гало-эффект. Возникает при объектных отношениях (не люблю Кляйн), может быть применим не только к людям, но и к инструментарию.
Переход от Blame Culture к Compassion Culture не решён — все коллективы успешно невротизированы, ведомы страхом и подчинением, с эмоциональной и вербальной депривацией. Subordinate Satisfaction даже у Google сейчас около 17%, и это считается нормальным повсеместно в Штатах.
Blame на русский прямо не переводиться и состоит из Accusation, Criticism, Punishment и Humiliation. Как раз то что принято у англоговорящих называть токсичным поведением.
Коллективов нет — есть стада и племена, с стандартными племенными "обычиями" и "ритуалами". Задачи достигнуть поставленной цели общими целями нет в принципе, потому что отношение к работе "мы — не продукт", "мы — не компания", "З/П платят — вот и чудно".
От бабушек едущих в забитом автобусе и орущих друг на друга — кому кто на ногу наступил, не особо отличается. Автобус поломается — подождут, и сядут на следующий, благо маршрут активный.
Такой же принцип используется в golang'e, только там ещё буфера (структуры) сортируются по частоте обращений — возможно будет полезно для вашего случая, так как там получается даже более чем в 10 раз быстрее.