METR разобрала, как у неё украли API-ключ: приложение, написанное с ИИ, при сбое проверки прав пускало всех
Лаборатория, которая тестирует модели для крупных разработчиков, опубликовала отчёт о двух инцидентах. В марте исследователь поднял на личном EC2-инстансе маленькое веб-приложение за входом через Google. В коде была ошибка fail-open: если проверка авторизации не срабатывала, приложение считало пользователя допущенным. Инстанс несколько дней смотрел в интернет, атакующий вытащил ключ к моделям, добавил свой SSH-ключ и три недели гонял чужие запросы.
Заметить было трудно: за кредиты METR не платила деньгами, так что счёт не рос, а внутренняя панель METR не показывала отклонённые по лимитам запросы. В мае пришла вторая волна: сканирование, перебор паролей, попытки через OAuth-токены и ошибка в публичном просмотрщике транскриптов с read-only SQL.
Выводы для любой команды: ключи только в секрет-хранилище, приложения с доступом к ключам делать fail-closed, на каждый ключ лимит и алерт по числу запросов, а не только по деньгам. Полный разбор цепочки на сайте.
@prog_stuff
Лаборатория, которая тестирует модели для крупных разработчиков, опубликовала отчёт о двух инцидентах. В марте исследователь поднял на личном EC2-инстансе маленькое веб-приложение за входом через Google. В коде была ошибка fail-open: если проверка авторизации не срабатывала, приложение считало пользователя допущенным. Инстанс несколько дней смотрел в интернет, атакующий вытащил ключ к моделям, добавил свой SSH-ключ и три недели гонял чужие запросы.
Заметить было трудно: за кредиты METR не платила деньгами, так что счёт не рос, а внутренняя панель METR не показывала отклонённые по лимитам запросы. В мае пришла вторая волна: сканирование, перебор паролей, попытки через OAuth-токены и ошибка в публичном просмотрщике транскриптов с read-only SQL.
Выводы для любой команды: ключи только в секрет-хранилище, приложения с доступом к ключам делать fail-closed, на каждый ключ лимит и алерт по числу запросов, а не только по деньгам. Полный разбор цепочки на сайте.
@prog_stuff
Один параметр readahead сократил обращения к диску в 12 раз, а io_uring тут ни при чём
Фернандо Симойнс разбирал, почему его встраиваемая СУБД на io_uring не выигрывала у обычного чтения на сканах. Тест: запрос Q6 из TPC-H по таблице в 1,2 GiB, файл открыт с
Без упреждающего чтения база отправила 195 тысяч запросов по 4 KiB, и почти столько же дошло до устройства: ядру нечего было склеивать. С окном readahead в 32 страницы запросов в очереди стало даже больше, 218 тысяч, но до диска добралось около 16 тысяч. Ядро объединило 93% соседних чтений, средний запрос вырос с 4,37 до 56,53 KiB.
Цена тоже есть: поток
@prog_stuff
Фернандо Симойнс разбирал, почему его встраиваемая СУБД на io_uring не выигрывала у обычного чтения на сканах. Тест: запрос Q6 из TPC-H по таблице в 1,2 GiB, файл открыт с
O_DIRECT, запросы на чтение уходят в очередь io_uring.Без упреждающего чтения база отправила 195 тысяч запросов по 4 KiB, и почти столько же дошло до устройства: ядру нечего было склеивать. С окном readahead в 32 страницы запросов в очереди стало даже больше, 218 тысяч, но до диска добралось около 16 тысяч. Ядро объединило 93% соседних чтений, средний запрос вырос с 4,37 до 56,53 KiB.
Цена тоже есть: поток
sqpoll, который опрашивает очередь вместо системных вызовов, съел 65% циклов процессора. Вывод автора в том, что io_uring не ускоряет сам по себе, а только даёт очередь, и без прогрева этой очереди последовательными чтениями выигрыша нет.@prog_stuff
Посмотрите, как выглядят 128 килобайт, если каждый бит — отдельное ферритовое колечко
Spacelab — европейская лаборатория, которую возили в грузовом отсеке шаттла. Компьютеры NASA туда не поставили: программа была европейской, и внутри работали три одинаковых французских миникомпьютера Mitra 125 MS. Один вёл саму лабораторию, второй эксперименты, третий стоял резервом.
Памяти в таком компьютере 128 килобайт, и собрана она на магнитных сердечниках: каждый бит — крошечное ферритовое кольцо на пересечении проводов, а значение бита — направление его намагниченности. На фото блок из семи плат, занимающий примерно треть корпуса. Боковая панель снимается вместе с ним: тепло здесь отводится через плотный контакт с этой панелью, без всякого обдува.
Кен Ширрифф разобрал модуль до отдельных проводов: как устроены плоскости сердечников, что делает плата драйверов и почему чтение здесь стирает прочитанное значение, так что его каждый раз приходится записывать обратно.
@prog_stuff
Spacelab — европейская лаборатория, которую возили в грузовом отсеке шаттла. Компьютеры NASA туда не поставили: программа была европейской, и внутри работали три одинаковых французских миникомпьютера Mitra 125 MS. Один вёл саму лабораторию, второй эксперименты, третий стоял резервом.
Памяти в таком компьютере 128 килобайт, и собрана она на магнитных сердечниках: каждый бит — крошечное ферритовое кольцо на пересечении проводов, а значение бита — направление его намагниченности. На фото блок из семи плат, занимающий примерно треть корпуса. Боковая панель снимается вместе с ним: тепло здесь отводится через плотный контакт с этой панелью, без всякого обдува.
Кен Ширрифф разобрал модуль до отдельных проводов: как устроены плоскости сердечников, что делает плата драйверов и почему чтение здесь стирает прочитанное значение, так что его каждый раз приходится записывать обратно.
@prog_stuff
👍2❤1
JetBrains не пропатчила собственный TeamCity, и через него вынесли бэкап сервиса Cadence, AWS-учётки и файлы из S3
Компания обновила отчёт об инциденте. Cadence, облачный сервис для запуска вычислений из PyCharm, использовал TeamCity для оркестрации задач. В нём была CVE-2026-63077 с выполнением команд без аутентификации, и с 8 по 24 августа атакующие сидели на
Что утекло: логины, имена, почта и IP пользователей; полный бэкап сервера за 2024 год; AWS IAM-пользователи с учётными данными; файлы в S3-бакетах JetBrains. Мог быть доступен исходный код, который пользователи синхронизировали из PyCharm. Затронуты ли бакеты клиентов, компания пока не установила.
Рекомендация JetBrains тем, кто подключал Cadence: считать скомпрометированным всё, к чему у сервиса был доступ, от ключей облаков до SSH и ключей подписи. Хронологию и список секретов на замену разобрали на сайте.
@prog_stuff
Компания обновила отчёт об инциденте. Cadence, облачный сервис для запуска вычислений из PyCharm, использовал TeamCity для оркестрации задач. В нём была CVE-2026-63077 с выполнением команд без аутентификации, и с 8 по 24 августа атакующие сидели на
api.cadence.jetbrains.com. Обнаружили 23-го, отключили 24-го. Формулировка JetBrains: «сервер должен был быть пропатчен, но не был».Что утекло: логины, имена, почта и IP пользователей; полный бэкап сервера за 2024 год; AWS IAM-пользователи с учётными данными; файлы в S3-бакетах JetBrains. Мог быть доступен исходный код, который пользователи синхронизировали из PyCharm. Затронуты ли бакеты клиентов, компания пока не установила.
Рекомендация JetBrains тем, кто подключал Cadence: считать скомпрометированным всё, к чему у сервиса был доступ, от ключей облаков до SSH и ключей подписи. Хронологию и список секретов на замену разобрали на сайте.
@prog_stuff
🙈2
Спрячьте задержку автодополнения между нажатием и отпусканием клавиши
Рюртьян Пул развивает Wirewiki — сервис для просмотра DNS-записей доменов, их истории, делегирования и настроек почты. Главная навигация там ищет среди 240 миллионов доменных имён, поэтому автор добился появления подсказок уже в следующем кадре.
Запрос уходит на
Автор набрал 100 доменов в обычном темпе и получил p99 в 121 мс. Задержку он считает от
Перерасход трафика ограничен алфавитом домена: 38 символов дают максимум
Рюртьян Пул развивает Wirewiki — сервис для просмотра DNS-записей доменов, их истории, делегирования и настроек почты. Главная навигация там ищет среди 240 миллионов доменных имён, поэтому автор добился появления подсказок уже в следующем кадре.
Запрос уходит на
keyDown, сразу после нажатия клавиши. Сервер получает набранный префикс и подготавливает варианты для всех допустимых следующих символов, а интерфейс показывает результат на keyUp. В бюджет попадают длительность нажатия, пауза до следующей клавиши и длительность следующего нажатия.Автор набрал 100 доменов в обычном темпе и получил p99 в 121 мс. Задержку он считает от
keyUp до готовности результата: p99 в 0 мс означает, что в 99% случаев данные приходят раньше отпускания клавиши. Для сравнения, экран с частотой 60 Гц обновляется каждые 16,7 мс.Перерасход трафика ограничен алфавитом домена: 38 символов дают максимум
(38 + 1) × 8 = 312 имён в ответе. На практике запрос приносит до 5 КБ, после сжатия — около 2,5 КБ. Приём стоит проверить там, где сеть быстрее пальцев пользователя.Не всё же работать, иногда можно и поиграть.
Разобрали пять способов пополнения баланса Steam. Один зачисляет деньги на кошелёк по логину за одну-две минуты с комиссией около 6%. Другой показывает итоговую сумму ещё до оплаты и подходит для регулярных небольших пополнений. Третий — маркетплейс, где условия зависят от выбранного продавца, но сделки защищены гарантиями площадки. Четвёртый предлагает пополнение и по логину, и через продажу игровых предметов почти без комиссии. Пятый не берёт свою комиссию, но добавляет разницу за счёт курса конвертации.
По каждому — реальная комиссия, лимиты и на что смотреть, чтобы не наткнуться на мошенников. Складывайте в сохранёнки, вдруг пригодится.
Разобрали пять способов пополнения баланса Steam. Один зачисляет деньги на кошелёк по логину за одну-две минуты с комиссией около 6%. Другой показывает итоговую сумму ещё до оплаты и подходит для регулярных небольших пополнений. Третий — маркетплейс, где условия зависят от выбранного продавца, но сделки защищены гарантиями площадки. Четвёртый предлагает пополнение и по логину, и через продажу игровых предметов почти без комиссии. Пятый не берёт свою комиссию, но добавляет разницу за счёт курса конвертации.
По каждому — реальная комиссия, лимиты и на что смотреть, чтобы не наткнуться на мошенников. Складывайте в сохранёнки, вдруг пригодится.
Интерпретатор WebAssembly ускорили в 2,2 раза, и автор объяснил каждую оптимизацию
Wasmi нужен там, где JIT запрещён или не помещается: плагины, микроконтроллеры, песочницы, смарт-контракты. Версия 2.0 по замерам проекта исполняет код в 2,2 раза быстрее 1.0 по геометрическому среднему, а пост Робина Фрайлера читается как учебник по устройству быстрых интерпретаторов.
Три источника ускорения: четыре режима dispatch вместо одного switch-loop (
Отдельная история про компилятор: Rust 1.92 включил
@prog_stuff
Wasmi нужен там, где JIT запрещён или не помещается: плагины, микроконтроллеры, песочницы, смарт-контракты. Версия 2.0 по замерам проекта исполняет код в 2,2 раза быстрее 1.0 по геометрическому среднему, а пост Робина Фрайлера читается как учебник по устройству быстрых интерпретаторов.
Три источника ускорения: четыре режима dispatch вместо одного switch-loop (
auto-dispatch сам выбирает threaded-код, где компилятор позволяет), новое IR с аккумуляторными регистрами вместо стековых смещений и append-only CodeMap, где вызов функции на горячем пути не делает ни одного lookup. Ячейки стека стали 64-битными, поэтому SIMD больше не стоит 8% обычному коду.Отдельная история про компилятор: Rust 1.92 включил
DestinationPropagation, и CoreMark у интерпретатора Stitch упал с 3000 до 2200. Похожую проблему нашли и в Wasmi, после исправления результат вырос с 2800 до 4200. Вывод: после обновления toolchain бенчмарки интерпретатора надо перепрогонять. Сравнение с Wasm3, WAMR и Wasmtime Pulley разобрали на сайте.@prog_stuff
❤🔥2
Утечку горутин теперь ищет сборщик мусора: как устроен новый профиль в Go 1.27
Обычный goroutine-профиль показывает, сколько горутин заблокировано, но не говорит, проснутся ли они. Команда Go объяснила, как профиль
На схеме из блога видно, куда это встроено в маркировку GC. Худший случай, цепочка горутин, каждая из которых держит примитив следующей, даёт O(n²) за цикл, поэтому профиль советуют снимать раз в несколько часов, а не постоянно. Не ловит ожидание сети, файлов и самодельных спинлоков. Пример с 116 зависшими воркерами и что включить у себя, на сайте.
@prog_stuff
Обычный goroutine-профиль показывает, сколько горутин заблокировано, но не говорит, проснутся ли они. Команда Go объяснила, как профиль
goroutineleak решает это через достижимость: горутина живая, если она не заблокирована или если канал либо мьютекс, на котором она ждёт, достижим из другой живой горутины. Всё, что осталось недостижимым после обхода, разбудить некому.На схеме из блога видно, куда это встроено в маркировку GC. Худший случай, цепочка горутин, каждая из которых держит примитив следующей, даёт O(n²) за цикл, поэтому профиль советуют снимать раз в несколько часов, а не постоянно. Не ловит ожидание сети, файлов и самодельных спинлоков. Пример с 116 зависшими воркерами и что включить у себя, на сайте.
@prog_stuff
Форк SQLite с ветками и merge дошёл до беты, и авторы честно назвали цену записи
DoltLite заменяет в SQLite B-tree на content-addressed Prolly Tree, а всё остальное, от парсера SQL до тестового harness, оставляет родным. Из-за этого база получает Git-подобные операции: branch, merge, diff, rebase, cherry-pick, reset, push и pull на свой remote или DoltHub. 31 августа проект объявил бету и версию 0.50.0.
Цифры совместимости серьёзные: 100%
Цена: в памяти чтение медленнее на 10%, запись на 60%; для файловых баз чтение на уровне SQLite, а вот мелкие autocommit-записи в 3,1 раза дольше, 400 мкс против 125. Каждое изменение порождает новые chunk с хешами, и на одиночной вставке это не амортизируется. Где такая база уместна, а где SQLite останется быстрее, разобрали на сайте.
@prog_stuff
DoltLite заменяет в SQLite B-tree на content-addressed Prolly Tree, а всё остальное, от парсера SQL до тестового harness, оставляет родным. Из-за этого база получает Git-подобные операции: branch, merge, diff, rebase, cherry-pick, reset, push и pull на свой remote или DoltHub. 31 августа проект объявил бету и версию 0.50.0.
Цифры совместимости серьёзные: 100%
sqllogictest из 5,8 млн запросов и 99,46% из 892 277 TCL-тестов самого SQLite. Оставшиеся 4809 расхождений упираются в архитектуру: нет rowid, chunk вместо page, нет WAL рядом с файлом.Цена: в памяти чтение медленнее на 10%, запись на 60%; для файловых баз чтение на уровне SQLite, а вот мелкие autocommit-записи в 3,1 раза дольше, 400 мкс против 125. Каждое изменение порождает новые chunk с хешами, и на одиночной вставке это не амортизируется. Где такая база уместна, а где SQLite останется быстрее, разобрали на сайте.
@prog_stuff
Прототип Cloudflare ужал текст в кэше в 2,8 раза, потратив на это несколько процентов CPU
Казалось бы, текст в интернете и так сжат. Но по замерам Cloudflare около 71% текстовых ответов приходят от origin-серверов без
Прототип Cache Transcoding внутри Pingora сжимает подходящие ответы zstd уровня 3 при записи в кэш, между дата-центрами гоняет их сжатыми и распаковывает перед клиентом. Кодирование стоит 4,31 нс на байт, декодирование 1,56 нс, коэффициент 2,834x на двух тестовых объектах, а не на всём кэше. Порог 4 КиБ отсёк мелочь и потерял всего 1% выигрыша.
Главная фраза статьи: стоимость кодирования платится один раз, когда объект попадает в кэш. Приём переносится на nginx с proxy_cache и Varnish без изменений в идее; порядок действий и где считать CPU разобрали на сайте.
@prog_stuff
Казалось бы, текст в интернете и так сжат. Но по замерам Cloudflare около 71% текстовых ответов приходят от origin-серверов без
Content-Encoding: сжимает уже edge, а на диск кэша объект ложится сырым. При этом HTML, JSON, CSS и JS дают 67,3% запросов и 22,3% байтов, а картинки и видео 21,4% запросов и 63,3% байтов, их пересжимать бессмысленно.Прототип Cache Transcoding внутри Pingora сжимает подходящие ответы zstd уровня 3 при записи в кэш, между дата-центрами гоняет их сжатыми и распаковывает перед клиентом. Кодирование стоит 4,31 нс на байт, декодирование 1,56 нс, коэффициент 2,834x на двух тестовых объектах, а не на всём кэше. Порог 4 КиБ отсёк мелочь и потерял всего 1% выигрыша.
Главная фраза статьи: стоимость кодирования платится один раз, когда объект попадает в кэш. Приём переносится на nginx с proxy_cache и Varnish без изменений в идее; порядок действий и где считать CPU разобрали на сайте.
@prog_stuff
Один младший бит: как реализация FMA вскрыла одинаковую ошибку в Rust std, std::simd и musl
Shnatsel переносил формально верифицированный алгоритм fused multiply-add в библиотеку
Ошибка живёт в программной эмуляции FMA, на железе с аппаратной инструкцией её нет: затронуты старые Intel без AVX2, Hygon и 32-битный ARM. Автор не берётся оценить практический ущерб, но называет сценарий, где это больно: детерминированные симуляции, которые обязаны давать одинаковые биты на разных машинах. Проверка из трёх hex-чисел и состояние патчей на сайте.
@prog_stuff
Shnatsel переносил формально верифицированный алгоритм fused multiply-add в библиотеку
fearless_simd, добавил тесты на миллион субнормальных значений и получил расхождение. Дальше оказалось, что f32::mul_add в стандартной библиотеке Rust ошибается ровно так же, как и fmaf() в musl, а контрпример к первой версии патча нашла языковая модель.Ошибка живёт в программной эмуляции FMA, на железе с аппаратной инструкцией её нет: затронуты старые Intel без AVX2, Hygon и 32-битный ARM. Автор не берётся оценить практический ущерб, но называет сценарий, где это больно: детерминированные симуляции, которые обязаны давать одинаковые биты на разных машинах. Проверка из трёх hex-чисел и состояние патчей на сайте.
@prog_stuff
👍2
Разработчик сделал бэкенд компилятора, чтобы написать игру для Game Boy на чистом Rust
Game Boy не является целью Rust даже на уровне Tier 3: процессор SM83 не поддерживается LLVM. Автор под ником zlfn начинал с SDCC и библиотеки GBDK, а закончил собственным форком LLVM с бэкендом Z80/SM83 и форком rustc с целью
Внутри есть Rust-библиотеки для графики, звука, ввода и консоли, упаковка кода в банки по 16 КиБ и собственный линкер. Готовый ROM
Автор предупреждает, что проект не тестировался вне его машины и это ранняя стадия. Но это редкий пример, когда «Rust везде» доказано не докладом, а бэкендом компилятора под восьмибитную приставку. Репозиторий на GitHub.
@prog_stuff
Game Boy не является целью Rust даже на уровне Tier 3: процессор SM83 не поддерживается LLVM. Автор под ником zlfn начинал с SDCC и библиотеки GBDK, а закончил собственным форком LLVM с бэкендом Z80/SM83 и форком rustc с целью
sm83. Теперь cargo-gb build собирает crate в ROM, а cargo-gb run сразу запускает эмулятор.Внутри есть Rust-библиотеки для графики, звука, ввода и консоли, упаковка кода в банки по 16 КиБ и собственный линкер. Готовый ROM
sprite.gb можно скачать и запустить в любом эмуляторе; исходник примера лежит в examples/sprite.Автор предупреждает, что проект не тестировался вне его машины и это ранняя стадия. Но это редкий пример, когда «Rust везде» доказано не докладом, а бэкендом компилятора под восьмибитную приставку. Репозиторий на GitHub.
@prog_stuff
❤🔥3
Стековый байткод против регистрового: замер на одном языке, одном железе и честной методике
Максим Шевалье-Буавер, в прошлом автор YJIT для Ruby, переписала VM своего языка Plush с стековой модели на регистровую и разложила, откуда взялось ускорение. Инструкция стала 64-битным словом с тремя операндами;
Методика: 11 чередующихся запусков на тест, медиана, повтор всего набора. Медиана ускорения 2,07 раза, максимум 3,37, тесты GC не сдвинулись. Против Lua 5.5.1 на
@prog_stuff
Максим Шевалье-Буавер, в прошлом автор YJIT для Ruby, переписала VM своего языка Plush с стековой модели на регистровую и разложила, откуда взялось ускорение. Инструкция стала 64-битным словом с тремя операндами;
a + b из трёх диспетчеризаций превратилось в одну. Сама смена модели дала 1,55 раза по геометрическому среднему, слитые сравнения-переходы, непосредственные операнды и свёртка констант добавили ещё 25%.Методика: 11 чередующихся запусков на тест, медиана, повтор всего набора. Медиана ускорения 2,07 раза, максимум 3,37, тесты GC не сдвинулись. Против Lua 5.5.1 на
fib быстрее на 24%. Главный урок автора: в интерпретаторе считайте инструкции, а не такты. Полный разбор на сайте.@prog_stuff
Модуль std ускорил сборку Seastar на 22% без единой правки в исходниках
Чуаньцы Сюй из команды Clang показал два способа подключить
Замер на Seastar, Clang и libc++ из ветки 24,
Из ограничений: нужен Clang 24 (в 23 автор ловил зависание), в module map нельзя включать заголовки с макросами вроде
@prog_stuff
Чуаньцы Сюй из команды Clang показал два способа подключить
import std; к проекту, который об этом не знает. Preload заставляет компилятор загружать BMI модуля std перед каждой единицей трансляции через -fmodule-file. Module Map идёт дальше: файл std.modulemap подменяет #include <vector> и остальные STL-заголовки на import std; автоматически.Замер на Seastar, Clang и libc++ из ветки 24,
-j8, медиана из трёх прогонов. Wall-time: 92,21 с с заголовками, 81,09 с с Preload, 71,55 с с Module Map, то есть минус 12% и минус 22%. Пользовательское CPU-время упало с 655,7 до 497,5 с. Память при Preload выросла на 2,7%, при Module Map снизилась на 3,3%.Из ограничений: нужен Clang 24 (в 23 автор ловил зависание), в module map нельзя включать заголовки с макросами вроде
cassert, а заголовки пришлось пробросить симлинками. Полный патч к CMake лежит в ветке автора, разбор в блоге.@prog_stuff
Двухчасовое расследование о том, откуда взялась фраза про преждевременную оптимизацию
Её полвека цитируют то как Кнута, то как Хоара, чаще всего чтобы осадить желание написать код побыстрее. Кейси Муратори собрал больше 200 исторических документов, от переписки Дейкстры времён «GOTO considered harmful» до отчётов конференций NATO 1968 года, и показал, при каких обстоятельствах фраза родилась и к чему её на самом деле применяли.
Попутно у Хоара в 1965 году нашлась конструкция, похожая на SSA-форму, а у Страуструпа в 1979-м приём, который сегодня называют dependency injection. В нашем канале Tproger разобрали подробнее.
@prog_stuff
Её полвека цитируют то как Кнута, то как Хоара, чаще всего чтобы осадить желание написать код побыстрее. Кейси Муратори собрал больше 200 исторических документов, от переписки Дейкстры времён «GOTO considered harmful» до отчётов конференций NATO 1968 года, и показал, при каких обстоятельствах фраза родилась и к чему её на самом деле применяли.
Попутно у Хоара в 1965 году нашлась конструкция, похожая на SSA-форму, а у Страуструпа в 1979-м приём, который сегодня называют dependency injection. В нашем канале Tproger разобрали подробнее.
@prog_stuff
Выделите всю память при старте и никогда больше: как TigerBeetle защищается от перегрузки
Алексей Кладов (matklad) отвечает на письмо читателя, который получил use-after-free в матчере ордеров с пулом объектов, и выводит из этого два приёма из TigerStyle. Первый: никакой динамической аллокации после инициализации. Программа запускается с
На возражение «а вдруг память ещё есть» ответ: а вдруг нет? Попытка выделить ещё один объект под нагрузкой заканчивается OOM-киллером, который снимает весь процесс с миллионом ордеров внутри, а то и супервизор. Со статическим лимитом система может не стартовать без памяти, но если стартовала, деградирует предсказуемо. По дороге разбирается, почему пул объектов одного типа превращает опасный use-after-free в скучный детерминированный баг.
@prog_stuff
Алексей Кладов (matklad) отвечает на письмо читателя, который получил use-after-free в матчере ордеров с пулом объектов, и выводит из этого два приёма из TigerStyle. Первый: никакой динамической аллокации после инициализации. Программа запускается с
--orders-max=1_000_000, выделяет массив под миллион ордеров одной строкой и всё, что сверх лимита, отклоняет.На возражение «а вдруг память ещё есть» ответ: а вдруг нет? Попытка выделить ещё один объект под нагрузкой заканчивается OOM-киллером, который снимает весь процесс с миллионом ордеров внутри, а то и супервизор. Со статическим лимитом система может не стартовать без памяти, но если стартовала, деградирует предсказуемо. По дороге разбирается, почему пул объектов одного типа превращает опасный use-after-free в скучный детерминированный баг.
@prog_stuff
Сколько знаков в 52 факториала и как прикинуть это без калькулятора
Началось с бытового вопроса: насколько велико число перестановок колоды карт. Дальше Эли Бендерски задумался, как оценивать такие величины, не имея под рукой ни калькулятора, ни компьютера.
Оказалось, что за оценкой количества знаков в факториале стоит вполне занятная математика, и разбор разворачивает её шаг за шагом, без предварительных знаний сверх школьных.
Жанр здесь не прикладной, а тот, ради которого такие блоги и читают: короткое погружение в тему, которая на работе не понадобится, но перестраивает интуицию про рост чисел.
Началось с бытового вопроса: насколько велико число перестановок колоды карт. Дальше Эли Бендерски задумался, как оценивать такие величины, не имея под рукой ни калькулятора, ни компьютера.
Оказалось, что за оценкой количества знаков в факториале стоит вполне занятная математика, и разбор разворачивает её шаг за шагом, без предварительных знаний сверх школьных.
Жанр здесь не прикладной, а тот, ради которого такие блоги и читают: короткое погружение в тему, которая на работе не понадобится, но перестраивает интуицию про рост чисел.
«Zero-cost» compile-time информация о типах стоит экспоненциально, а runtime-таблица линейно
Джинджер Билл, автор языка Odin, объясняет, почему Odin форматирует вывод через RTTI, а не через генерацию кода на этапе компиляции. Таблица типов растёт линейно: N типов, N записей, одна процедура печати на все, ноль дополнительной работы у семантического анализатора. Её размер можно прочитать в бинарнике в байтах.
CTTI специализирует код под каждый тип и каждую комбинацию: сериализатор N типов в K форматов даёт N на K инстанциаций, и это повторяется в проверке типов, кодогенерации и размере бинарника. Цену этого никто не может назвать в цифрах, потому что она размазана по компилятору, зато её называют «бесплатной». Автор аккуратно разводит «известно на этапе компиляции» и «бесплатно перечислить на этапе компиляции»: это разные вещи.
@prog_stuff
Джинджер Билл, автор языка Odin, объясняет, почему Odin форматирует вывод через RTTI, а не через генерацию кода на этапе компиляции. Таблица типов растёт линейно: N типов, N записей, одна процедура печати на все, ноль дополнительной работы у семантического анализатора. Её размер можно прочитать в бинарнике в байтах.
CTTI специализирует код под каждый тип и каждую комбинацию: сериализатор N типов в K форматов даёт N на K инстанциаций, и это повторяется в проверке типов, кодогенерации и размере бинарника. Цену этого никто не может назвать в цифрах, потому что она размазана по компилятору, зато её называют «бесплатной». Автор аккуратно разводит «известно на этапе компиляции» и «бесплатно перечислить на этапе компиляции»: это разные вещи.
@prog_stuff
Задержка, пропускная способность или цена токена: карта компромиссов инференса LLM
Филип Кили из Baseten раскладывает все приёмы ускорения инференса на две группы. Одни двигают развёртывание вдоль кривой компромисса: размер батча (маленький даёт низкую задержку и дорогой токен, большой наоборот), tensor parallelism с дорогой all-to-all коммуникацией ради задержки, expert parallelism, который на широких MoE может занимать целую стойку. Другие сдвигают саму кривую: квантизация в MXFP4 и NVFP4, оптимизация ядер, speculative decoding (EAGLE-3, DSpark, DFlash), разнесение prefill и decode по разным воркерам.
Полезная арифметика: удвоение производительности железа и удвоение софтверного слоя вместе дают четырёхкратный выигрыш. И честная оговорка: на практике фронтир зубчатый, и попадание в целевые числа чаще вопрос перебора конфигураций, чем новой идеи.
@prog_stuff
Филип Кили из Baseten раскладывает все приёмы ускорения инференса на две группы. Одни двигают развёртывание вдоль кривой компромисса: размер батча (маленький даёт низкую задержку и дорогой токен, большой наоборот), tensor parallelism с дорогой all-to-all коммуникацией ради задержки, expert parallelism, который на широких MoE может занимать целую стойку. Другие сдвигают саму кривую: квантизация в MXFP4 и NVFP4, оптимизация ядер, speculative decoding (EAGLE-3, DSpark, DFlash), разнесение prefill и decode по разным воркерам.
Полезная арифметика: удвоение производительности железа и удвоение софтверного слоя вместе дают четырёхкратный выигрыш. И честная оговорка: на практике фронтир зубчатый, и попадание в целевые числа чаще вопрос перебора конфигураций, чем новой идеи.
@prog_stuff