Список, который стоит открывать каждый раз, когда садитесь писать что-то с датами: «Заблуждения программистов о времени» Ноа Сассмана. Тридцать четыре утверждения, каждое из которых кажется очевидно верным и каждое неверно. Во второй части их ещё семьдесят девять.
Выборочно: в сутках не всегда 24 часа. Часовой пояс машины не совпадает с поясом пользователя. Часовые пояса меняются политическим решением, а переходы на летнее время не постоянны. Часы клиента и сервера не совпадают. Минута на часах не всегда равна минуте реального времени. Временные метки не обязаны быть уникальными. Время события, время записи в журнал и время получения сообщения — три разных момента.
Любимый пример оттуда: виртуальная машина, приостановленная на два часа, после запуска продолжила считать, что всё ещё час дня.
Вторая часть добирается до високосных секунд, разницы между настенными и монотонными часами и до того, почему
@prog_stuff
Выборочно: в сутках не всегда 24 часа. Часовой пояс машины не совпадает с поясом пользователя. Часовые пояса меняются политическим решением, а переходы на летнее время не постоянны. Часы клиента и сервера не совпадают. Минута на часах не всегда равна минуте реального времени. Временные метки не обязаны быть уникальными. Время события, время записи в журнал и время получения сообщения — три разных момента.
Любимый пример оттуда: виртуальная машина, приостановленная на два часа, после запуска продолжила считать, что всё ещё час дня.
Вторая часть добирается до високосных секунд, разницы между настенными и монотонными часами и до того, почему
sleep(1000) не значит «ровно секунда».@prog_stuff
👍1
Профилировщик показывает, что горячая функция ждёт память. Дальше начинается гадание: какое именно поле какой структуры не влезает в кэш.
Группа из Университета штата Северная Каролина и Google сделала профилировщик, который отвечает на этот вопрос прямо: каждое обращение к памяти связывается с конкретным типом и полем внутри него. Работает поверх штатного
Проверяли на ядре Linux 6.17, memcached, Redis, Git, FFmpeg и Binutils. Покрытие типов для обычной сборки Ubuntu — 92,7 процента, циклов ядра — больше 90. У FFmpeg покрытие циклов всего 40 процентов, потому что там много рукописного векторного кода без отладочной информации.
Пример находки: в нагрузке MySQL на 256 серверах структура
@prog_stuff
Группа из Университета штата Северная Каролина и Google сделала профилировщик, который отвечает на этот вопрос прямо: каждое обращение к памяти связывается с конкретным типом и полем внутри него. Работает поверх штатного
perf и отладочной информации, накладных расходов во время работы программы не добавляет, потому что разбор идёт офлайн.Проверяли на ядре Linux 6.17, memcached, Redis, Git, FFmpeg и Binutils. Покрытие типов для обычной сборки Ubuntu — 92,7 процента, циклов ядра — больше 90. У FFmpeg покрытие циклов всего 40 процентов, потому что там много рукописного векторного кода без отладочной информации.
Пример находки: в нагрузке MySQL на 256 серверах структура
cfs_rq из планировщика занимала 7,58 процента циклов ядра и давала 49,02 процента промахов последнего уровня кэша. Перестановка полей внутри структуры этот вклад заметно снизила.@prog_stuff
20 августа на crates.io вышла версия 0.3.10 крейта
Настоящий крейт называется
Отдельный ход: с того же аккаунта отозвали версии с 0.3.5 по 0.3.9. Cargo на отозванную версию предлагает обновиться, и единственной неотозванной оставалась 0.3.10.
Rust Security Response Team сообщила, что 0.3.10 была доступна 86 минут: опубликована в 07:15 UTC, удалена в 08:41. Отозванные версии вернули, аккаунт заблокировали. Задеты ещё
@prog_stuff
arrayref. Исходники макросов в ней прежние, в манифесте одно изменение — добавлена зависимость proc-macro1 версии 1.0.107.Настоящий крейт называется
proc-macro2, а proc-macro1 — типосквот с подделанным полем authors под именем Дэвида Толная; его src/ копирует proc-macro2, поэтому сборка продолжала работать. Вредонос лежит в сборочном скрипте: адрес сервера собирается из base64-фрагментов, бинарник качается по TLS без проверки сертификата и запускается отдельно от сборки. Срабатывает во время компиляции — достаточно просто собрать проект.Отдельный ход: с того же аккаунта отозвали версии с 0.3.5 по 0.3.9. Cargo на отозванную версию предлагает обновиться, и единственной неотозванной оставалась 0.3.10.
Rust Security Response Team сообщила, что 0.3.10 была доступна 86 минут: опубликована в 07:15 UTC, удалена в 08:41. Отозванные версии вернули, аккаунт заблокировали. Задеты ещё
internment 0.8.7 и append-only-vec 0.1.9.@prog_stuff
Обычная модель угроз для защиты от шифровальщиков предполагает, что операционная система на нашей стороне. Группа из Мичиганского университета взяла модель пожёстче: атакующий контролирует ядро, файловую систему, драйверы, гипервизор и даже привилегированного администратора.
Защита вынесена ниже всего этого — на уровень блочного устройства. Физический блок нельзя перезаписать до истечения заданного интервала, состояние блоков ведётся в журнале, который можно только дополнять, а каждая операция проверяется перед записью. То есть шифровальщик может записать свои данные, но не может стереть старые.
Прототип собран как блочный драйвер для ext4 на Raspberry Pi с обычными диском и твердотельным накопителем. Ядро проверяющей части занимает около 400 строк кода, а свойства «обход невозможен» и «восстановление корректно» доказаны формально в Dafny.
Проверили на 18 семействах программ-вымогателей: файловую систему удалось восстановить в каждом случае. Накладные расходы — 0,4 процента по времени и 0,5 процента по пропускной способности накопителя, счётчики занимают около 2 мегабайт на терабайт данных.
@prog_stuff
Защита вынесена ниже всего этого — на уровень блочного устройства. Физический блок нельзя перезаписать до истечения заданного интервала, состояние блоков ведётся в журнале, который можно только дополнять, а каждая операция проверяется перед записью. То есть шифровальщик может записать свои данные, но не может стереть старые.
Прототип собран как блочный драйвер для ext4 на Raspberry Pi с обычными диском и твердотельным накопителем. Ядро проверяющей части занимает около 400 строк кода, а свойства «обход невозможен» и «восстановление корректно» доказаны формально в Dafny.
Проверили на 18 семействах программ-вымогателей: файловую систему удалось восстановить в каждом случае. Накладные расходы — 0,4 процента по времени и 0,5 процента по пропускной способности накопителя, счётчики занимают около 2 мегабайт на терабайт данных.
@prog_stuff
Если хочется разобраться в криптографии руками, а не по формулам, есть Cryptopals — восемь наборов заданий, где вы последовательно ломаете реальные конструкции.
Устроено так: предварительных знаний криптографии не требуется, нужен только уверенный навык программирования, а язык любой. Каждое задание решается кодом, а не угадыванием.
Первый набор — разминка: hex, Base64, XOR одним байтом, XOR повторяющимся ключом, обнаружение режима ECB. Второй уже интереснее: дополнение по PKCS#7, режим CBC, оракул выбора режима, переворот битов в CBC. Дальше — потоковые шифры, генераторы случайных чисел и повторное использование одноразового значения. Затем атака посредника на обмен ключами Диффи-Хеллмана, подмена параметров группы. Ближе к концу — восстановление сообщений RSA, слабые одноразовые значения в подписях, оракулы дополнения.
Почему это не устарело за тринадцать лет: ECB, оракул дополнения, повторно использованный nonce и плохая случайность — это классы ошибок, а не конкретные библиотеки. Оговорка авторов тоже важна: набор учит ломать, но не является руководством по выбору криптографии для продакшена.
@prog_stuff
Устроено так: предварительных знаний криптографии не требуется, нужен только уверенный навык программирования, а язык любой. Каждое задание решается кодом, а не угадыванием.
Первый набор — разминка: hex, Base64, XOR одним байтом, XOR повторяющимся ключом, обнаружение режима ECB. Второй уже интереснее: дополнение по PKCS#7, режим CBC, оракул выбора режима, переворот битов в CBC. Дальше — потоковые шифры, генераторы случайных чисел и повторное использование одноразового значения. Затем атака посредника на обмен ключами Диффи-Хеллмана, подмена параметров группы. Ближе к концу — восстановление сообщений RSA, слабые одноразовые значения в подписях, оракулы дополнения.
Почему это не устарело за тринадцать лет: ECB, оракул дополнения, повторно использованный nonce и плохая случайность — это классы ошибок, а не конкретные библиотеки. Оговорка авторов тоже важна: набор учит ломать, но не является руководством по выбору криптографии для продакшена.
@prog_stuff
👍1
Как тестировать сервис, у которого 96 операций в API, больше 500 триллионов объектов и свыше 200 миллионов запросов в секунду? Инженеры Amazon описали свой подход на примере S3: рядом с настоящим сервисом живёт исполняемая эталонная модель, которая хранит состояние и сверяет с ним каждый ответ.
Сценарии к модели не пишутся руками и не берутся случайно. Поведение раскладывается на признаки: например, для чтения объекта учитываются 21 параметр запроса, 36 параметров ответа и само содержимое. В одном из экспериментов из 37 признаков получилось 135 категорий поведения и 1025 качественно различных сценариев, которые и генерируются целенаправленно.
Сравнение с обычным тестированием на свойствах показательно: там 28 457 запросов дали 9040 уникальных сценариев, остальные 19 417 оказались повторами. У направленной генерации трёхчасовая кампания выполняет около 432 000 запросов.
В трёх запусках в конвейере сборки модель поймала 171, 92 и 109 расхождений поведения — среди них десятки настоящих проблем, которые иначе уехали бы дальше.
@prog_stuff
Сценарии к модели не пишутся руками и не берутся случайно. Поведение раскладывается на признаки: например, для чтения объекта учитываются 21 параметр запроса, 36 параметров ответа и само содержимое. В одном из экспериментов из 37 признаков получилось 135 категорий поведения и 1025 качественно различных сценариев, которые и генерируются целенаправленно.
Сравнение с обычным тестированием на свойствах показательно: там 28 457 запросов дали 9040 уникальных сценариев, остальные 19 417 оказались повторами. У направленной генерации трёхчасовая кампания выполняет около 432 000 запросов.
В трёх запусках в конвейере сборки модель поймала 171, 92 и 109 расхождений поведения — среди них десятки настоящих проблем, которые иначе уехали бы дальше.
@prog_stuff
Самый быстрый известный алгоритм печати double безымянный: он живёт в файле
Классический Schubfach на каждое число делает два-три 192-битных умножения. Здесь ядро работает на целых фиксированной ширины и обходится одним умножением на заранее вычисленную степень десяти. Дальше рассматриваются четыре кандидата на округление и выбирается кратчайшее корректное представление с округлением к чётному. Отдельно разобран пограничный случай, где алгоритм выбирает между
Автор использует тот же алгоритм в своей библиотеке Żmij. К тексту приложен интерактивный визуализатор на формате E4M3 из 256 кодировок, на котором видно, как работает каждый шаг.
@prog_stuff
yy_double.c внутри JSON-библиотеки yyjson, написан её автором ibireme и почти нигде не описан. Виктор Зверович, автор {fmt}, разобрал, как он устроен и за счёт чего входит в число самых быстрых.Классический Schubfach на каждое число делает два-три 192-битных умножения. Здесь ядро работает на целых фиксированной ширины и обходится одним умножением на заранее вычисленную степень десяти. Дальше рассматриваются четыре кандидата на округление и выбирается кратчайшее корректное представление с округлением к чётному. Отдельно разобран пограничный случай, где алгоритм выбирает между
2e2 и более длинным 19e1, и на первый взгляд это похоже на баг.Автор использует тот же алгоритм в своей библиотеке Żmij. К тексту приложен интерактивный визуализатор на формате E4M3 из 256 кодировок, на котором видно, как работает каждый шаг.
@prog_stuff
В LLVM 23 время компиляции сократилось на 6,75 процента, а на sqlite3 — на 10,53. Никакого одного крупного изменения за этим нет: Александр Энгельке собрал по частям, откуда взялись эти проценты.
Хеш-таблицы перевели с квадратичного пробирования на линейное и избавились от ключей-надгробий:
Отдельная линия — GlobalISel на AArch64
@prog_stuff
Хеш-таблицы перевели с квадратичного пробирования на линейное и избавились от ключей-надгробий:
DenseMap дал −1,27 процента, SmallPtrSet −0,24, StringMap −0,10. Хеш-функцию сменили с CityHash на xxh3. В SmallVector путь роста вынесли из тела push_back, чтобы разрешить хвостовой вызов, — ещё −0,50.Отдельная линия — GlobalISel на AArch64
-O0: отставание от FastISel упало с 12,71 до 9,39 процента. Автор оговаривает, что любимую свою правку тут потом откатили.@prog_stuff
Одна строка
В коде видна попытка переопределить
Отдельная часть текста про ревью: автор сравнивает обычный коммит на 15 строк и 235 символов описания с подозрительным изменением на 1534 строки и 5 символов в сообщении. Это независимый разбор, а не официальный отчёт Coldcard, о чём в тексте сказано прямо.
@prog_stuff
#define MICROPY_HW_ENABLE_RNG (0) отключила аппаратный генератор случайных чисел на STM32, и прошивка аппаратного кошелька молча перешла на слабый программный Yasmarang. Гостевой разбор на btc++ по мотивам истории с Coldcard показывает, как это осталось незамеченным.В коде видна попытка переопределить
pyb_rng_get под собственный источник энтропии, рядом комментарий «у нас своя версия этого кода». Но make_new_wallet() вызывал random.bytes(32), а тот шёл другим путём, через rng_get(), и в итоге брал числа из генератора, который годится для игр, а не для ключей. Код исполнялся без ошибок и честно возвращал 32 байта.Отдельная часть текста про ревью: автор сравнивает обычный коммит на 15 строк и 235 символов описания с подозрительным изменением на 1534 строки и 5 символов в сообщении. Это независимый разбор, а не официальный отчёт Coldcard, о чём в тексте сказано прямо.
@prog_stuff
Как понять, что программисту пора в отпуск:
— на столе бардак;
— шорты не доставались с позапрошлого лета;
— чудится тифлинг;
— на вопрос «когда отдыхаешь?» отвечает «после релиза»;
— релиз был в феврале.
Сам он с места не сдвинется. Помогите Типичному Программисту собраться и улететь в отпуск в новой мини-игре!
— на столе бардак;
— шорты не доставались с позапрошлого лета;
— чудится тифлинг;
— на вопрос «когда отдыхаешь?» отвечает «после релиза»;
— релиз был в феврале.
Сам он с места не сдвинется. Помогите Типичному Программисту собраться и улететь в отпуск в новой мини-игре!
😁5
ELF — это база данных, которая отказывается в этом признаться:
Фарид Закария довёл мысль до конца. Его прототип SELF — исполняемый файл, который целиком является базой SQLite:
Отсюда
Цена: около 5 миллисекунд на старте и страницы, которые копируются из b-дерева вместо отображения в память.
@prog_stuff
.strtab делает интернирование строк, .gnu.hash работает индексом, таблица заголовков секций — это таблица таблиц, а st_name — внешний ключ, разложенный руками.Фарид Закария довёл мысль до конца. Его прототип SELF — исполняемый файл, который целиком является базой SQLite:
file hello показывает «SQLite 3.x database», ./hello печатает Hello, world!, а sqlite3 hello 'SELECT soname FROM ldd' отвечает libc.so.6. Запуск идёт через binfmt_misc и отдельный интерпретатор.Отсюда
strip — это DELETE и VACUUM, patchelf — UPDATE, а LD_PRELOAD — строка в таблице, которую можно включить и откатить транзакцией.Цена: около 5 миллисекунд на старте и страницы, которые копируются из b-дерева вместо отображения в память.
@prog_stuff
На скриншоте ролик, к которому YouTube показывает пометку «снято камерой». Внутри — рендер из Big Buck Bunny.
Дэвид Бьюкенен разобрал, почему C2PA на Android так подделывается. Приложения-камеры опираются на Key Attestation и Play Integrity, а рут, полученный через эксплойт, обе проверки не тревожит: загрузчик остаётся заблокированным, ключи AVB — вендорскими, и серверы Google спокойно выдают устройству ключи подписи. Сам ключ из StrongBox не вытащить, но попросить Titan M2 подписать произвольные данные рут может.
Проверял автор на Pixel 8a и 9a, рут брал одноклик-эксплойтом CVE-2026-43499, который на полностью обновлённых Pixel всё ещё работает. Приложение Pixel Camera при этом имеет Assurance Level 2 — высший из определённых сейчас уровней программы соответствия C2PA.
Google закрыла отчёт как «Won't fix (infeasible)», выплатила 7500 долларов, а плашка у ролика после публикации исчезла — автор считает, что её сняли руками.
@prog_stuff
Дэвид Бьюкенен разобрал, почему C2PA на Android так подделывается. Приложения-камеры опираются на Key Attestation и Play Integrity, а рут, полученный через эксплойт, обе проверки не тревожит: загрузчик остаётся заблокированным, ключи AVB — вендорскими, и серверы Google спокойно выдают устройству ключи подписи. Сам ключ из StrongBox не вытащить, но попросить Titan M2 подписать произвольные данные рут может.
Проверял автор на Pixel 8a и 9a, рут брал одноклик-эксплойтом CVE-2026-43499, который на полностью обновлённых Pixel всё ещё работает. Приложение Pixel Camera при этом имеет Assurance Level 2 — высший из определённых сейчас уровней программы соответствия C2PA.
Google закрыла отчёт как «Won't fix (infeasible)», выплатила 7500 долларов, а плашка у ролика после публикации исчезла — автор считает, что её сняли руками.
@prog_stuff
Тип
24 августа PR из восемнадцати коммитов влили в
Помимо самой стабилизации в патче ещё три вещи. Fallback никогда-типа теперь
Речь про nightly; в стабильную ветку изменение приедет обычным циклом релизов.
Сам автор описал ощущение от финала так: «Чувствую себя… пустым. Прямо как never type».
@prog_stuff
! в Rust обозначает значение, которого не бывает: его «возвращает» функция, которая не возвращается никогда. Нестабильным он пробыл десять лет.24 августа PR из восемнадцати коммитов влили в
rust-lang/rust:main. Автор под ником WaffleLapkin пишет, что занимался стабилизацией больше двух лет, а до него было пять неудавшихся попыток.Помимо самой стабилизации в патче ещё три вещи. Fallback никогда-типа теперь
! во всех редакциях, и это ломающее изменение — под него гоняли Crater по экосистеме. std․convert․Infallible стал псевдонимом !, то есть из pub enum превратился в pub type. Линт dependency_on_unit_never_type_fallback удалён: подсказывать больше не о чем.Речь про nightly; в стабильную ветку изменение приедет обычным циклом релизов.
Сам автор описал ощущение от финала так: «Чувствую себя… пустым. Прямо как never type».
@prog_stuff
Отладочная сборка Firefox линкуется у lld за 4,44 секунды, у mold — за 0,89. Разница видна на графике: mold почти всю линковку держит занятыми 32 ядра, а lld преимущественно работает на одном ядре, изредка выходя в многоядерные всплески.
Руи Уэяма, автор mold, разобрал устройство своего линкера в статье от 24 августа. Ускоряли не отдельные проходы, а весь конвейер: разбор всех входных файлов, включая каждый элемент архивов, разрешение символов отдельным проходом через атомарный compare-and-swap, сборка мусора по секциям, слияние строк и запись результата. На девяти больших проектах mold быстрее lld в 2,4–16,1 раза и до 112 раз — GNU ld.
Одним проходом ускорение не объясняется: оставить последовательными копирование вывода и применение релокаций — и время линковки растёт на 542 процента.
Цена — эвристика: порядок разрешения конфликтов символов между общими библиотеками стандарт не описывает, mold выбирает его сам. Проверяли сборкой всего Gentoo: из 19 000 с лишним пакетов не собрались два.
@prog_stuff
Руи Уэяма, автор mold, разобрал устройство своего линкера в статье от 24 августа. Ускоряли не отдельные проходы, а весь конвейер: разбор всех входных файлов, включая каждый элемент архивов, разрешение символов отдельным проходом через атомарный compare-and-swap, сборка мусора по секциям, слияние строк и запись результата. На девяти больших проектах mold быстрее lld в 2,4–16,1 раза и до 112 раз — GNU ld.
Одним проходом ускорение не объясняется: оставить последовательными копирование вывода и применение релокаций — и время линковки растёт на 542 процента.
Цена — эвристика: порядок разрешения конфликтов символов между общими библиотеками стандарт не описывает, mold выбирает его сам. Проверяли сборкой всего Gentoo: из 19 000 с лишним пакетов не собрались два.
@prog_stuff
Венсан Берна собрал введение в spanning tree, где схемы не нарисованы, а работают. В браузере крутится настоящий демон MSTPD, скомпилированный в WebAssembly через emscripten: код, который обычно говорит с ядром Linux, заменён на C API — он заводит мосты и порты, отдаёт состояние в JSON и двигает время детерминированно.
Дальше можно ронять кабели и смотреть по шагам, вперёд и назад, как дерево пересобирается и какой порт уходит в блокировку. Чтобы понять, сошлась ли топология, автор после каждого шага сохраняет снимок памяти симуляции, проигрывает пятьдесят секунд модельного времени и откатывается к снимку.
Сорок юнит-тестов на эту обвязку проходят за 396 миллисекунд.
Чтения на тридцать шесть минут, и RSS-читалка не подойдёт: примеры живут только на странице.
@prog_stuff
Дальше можно ронять кабели и смотреть по шагам, вперёд и назад, как дерево пересобирается и какой порт уходит в блокировку. Чтобы понять, сошлась ли топология, автор после каждого шага сохраняет снимок памяти симуляции, проигрывает пятьдесят секунд модельного времени и откатывается к снимку.
Сорок юнит-тестов на эту обвязку проходят за 396 миллисекунд.
Чтения на тридцать шесть минут, и RSS-читалка не подойдёт: примеры живут только на странице.
@prog_stuff
❤1👍1
«x86 выполняет обращения к памяти строго по порядку, а ARM и RISC-V переставляют их как хотят, поэтому слабая модель памяти масштабируется лучше». Фабиан Гизен объясняет, почему эта формула ошибочна с обеих сторон.
За исключением совсем маленьких ядер и микроконтроллеров без кэша, процессоры вообще не соблюдают собственную модель памяти на каждом обращении. Они обещают вести себя так, как если бы соблюдали, и разница здесь принципиальная. Реализуют это оптимистично: считают, что данные никто параллельно не менял и что запись никем не оспаривается, выполняют обращения в удобном порядке, а рядом держат ровно столько метаданных, чтобы задним числом заметить нарушение порядка. Заметили — инструкция не фиксируется, состояние откатывается на момент до её выполнения, дальше повтор.
Так устроены все, независимо от модели памяти. Разница в другом: сколько метаданных нужно хранить для каждой обращающейся к памяти инструкции в полёте и какие порядки разрешено фиксировать при конфликте. Сильная модель чаще признаёт конфликт и уходит на повтор, слабая допускает больше законных порядков для расслабленных чтений и записей. При этом конфликт — медленный случай на любой архитектуре.
Часто цитируемые 7 процентов на аппаратный TSO у Apple Silicon Гизен отдельно снабжает оговоркой: это цена конкретной реализации, где TSO включается ради Rosetta и не является основным режимом ядра, спроектированного под AArch64.
Личное правило автора для многопоточного кода: конкурировать за общие данные реже, а не быстрее.
@prog_stuff
За исключением совсем маленьких ядер и микроконтроллеров без кэша, процессоры вообще не соблюдают собственную модель памяти на каждом обращении. Они обещают вести себя так, как если бы соблюдали, и разница здесь принципиальная. Реализуют это оптимистично: считают, что данные никто параллельно не менял и что запись никем не оспаривается, выполняют обращения в удобном порядке, а рядом держат ровно столько метаданных, чтобы задним числом заметить нарушение порядка. Заметили — инструкция не фиксируется, состояние откатывается на момент до её выполнения, дальше повтор.
Так устроены все, независимо от модели памяти. Разница в другом: сколько метаданных нужно хранить для каждой обращающейся к памяти инструкции в полёте и какие порядки разрешено фиксировать при конфликте. Сильная модель чаще признаёт конфликт и уходит на повтор, слабая допускает больше законных порядков для расслабленных чтений и записей. При этом конфликт — медленный случай на любой архитектуре.
Часто цитируемые 7 процентов на аппаратный TSO у Apple Silicon Гизен отдельно снабжает оговоркой: это цена конкретной реализации, где TSO включается ради Rosetta и не является основным режимом ядра, спроектированного под AArch64.
Личное правило автора для многопоточного кода: конкурировать за общие данные реже, а не быстрее.
@prog_stuff
Big Pineapple — платформа, на которой у Cloudflare работают 1.1.1.1, Gateway DNS, DNS Firewall и AS112, — держит в памяти больше 250 миллиардов записей кэша. Пять правок в том, как одна запись там лежит, вернули компании около 100 терабайт: столько оперативной памяти стоит примерно в 130 серверах их тринадцатого поколения.
Компания разобрала все пять по порядку.
@prog_stuff
Компания разобрала все пять по порядку.
Vec и String заменили на Box<[T]> и Box<str>: поле capacity бесполезно там, где запись после создания уже не меняется, а это 8 байт на поле и 64 байта на запись. Три списка DNS-секций свернули в один список с двумя смещениями по u16 — минус ещё 28 байт. Крупные варианты enum убрали в кучу, чтобы размер записи не диктовал самый жирный из них.@prog_stuff
Крейт из одной строчки показал, что Rustdoc делает лишнюю работу на каждой сборке
Перед каждым стабильным релизом Rust команда прогоняет Crater — инструмент, который собирает новой версией компилятора всю публичную экосистему. В прошлом месяце Crater нашёл, что бета-Rustdoc падает на крейте
Rustc такой код компилирует спокойно. Rustdoc падает с «reached the configured maximum number of stack frames», разбирая внутренний трейт
Формально это не регресс: число кадров стека не входит в гарантии стабильности. Но Ноа Лев из команды Rustdoc зацепился за другое — с какой стати почти пустому крейту вообще инлайнить документацию трейта из
За неделю разбора и серии PR среднее время работы упало на 25%, то есть Rustdoc стал быстрее на 33%. На реальных крейтах вроде
Автор прошёл весь путь по шагам: от странного сообщения на Zulip до профилирования и правок, попутно объясняя, как Rustdoc устроен изнутри и почему он так тесно завязан на внутренние API компилятора.
@prog_stuff
Перед каждым стабильным релизом Rust команда прогоняет Crater — инструмент, который собирает новой версией компилятора всю публичную экосистему. В прошлом месяце Crater нашёл, что бета-Rustdoc падает на крейте
indented-blocks. Весь крейт — одна строчка #![recursion_limit = "8"], ничего больше.Rustc такой код компилирует спокойно. Rustdoc падает с «reached the configured maximum number of stack frames», разбирая внутренний трейт
NumBufferTrait из core::fmt.Формально это не регресс: число кадров стека не входит в гарантии стабильности. Но Ноа Лев из команды Rustdoc зацепился за другое — с какой стати почти пустому крейту вообще инлайнить документацию трейта из
core::fmt, который никто не переэкспортирует. Логи подтвердили, что Rustdoc действительно лезет за ним.За неделю разбора и серии PR среднее время работы упало на 25%, то есть Rustdoc стал быстрее на 33%. На реальных крейтах вроде
hyper и bitmaps выигрыш доходит до 40%, на микробенчмарках вроде helloworld — до 60%.Автор прошёл весь путь по шагам: от странного сообщения на Zulip до профилирования и правок, попутно объясняя, как Rustdoc устроен изнутри и почему он так тесно завязан на внутренние API компилятора.
@prog_stuff
❤🔥2
«TUI лучше, потому что с клавиатуры» — аргумент, который держится на плохих GUI
На Hacker News неделю назад обсуждали призыв перестать делать текстовые интерфейсы в терминале и делать графические. Спор вышел живой, и в защиту TUI регулярно звучало одно и то же: их предпочитают, потому что они управляются с клавиатуры.
Хараламбос Кардарис разбирает именно этот довод. Наблюдение он не оспаривает: возьмите наугад графическое приложение и терминальное, второе с большей вероятностью окажется полностью клавиатурным. Но отсюда не следует, что делать надо TUI. Следует, что клавиатурная навигация во многих GUI сделана плохо.
Ничто не мешает графическому приложению управляться с клавиатуры так же полно, как терминальному, и лучше. Руководства по интерфейсам это прямо требуют: в GNOME Human Interface Guidelines написано, что всякое действие, выполнимое указателем, должно быть выполнимо и с клавиатуры, и что по любой части интерфейса нужно уметь пройти без мыши. Рекомендация есть, соблюдают её выборочно.
Сам автор — тяжёлый пользователь терминала и от TUI не отговаривает. Его претензия к рассуждению: клавиатурность зависит от того, как написана программа, и средой не задаётся.
@prog_stuff
На Hacker News неделю назад обсуждали призыв перестать делать текстовые интерфейсы в терминале и делать графические. Спор вышел живой, и в защиту TUI регулярно звучало одно и то же: их предпочитают, потому что они управляются с клавиатуры.
Хараламбос Кардарис разбирает именно этот довод. Наблюдение он не оспаривает: возьмите наугад графическое приложение и терминальное, второе с большей вероятностью окажется полностью клавиатурным. Но отсюда не следует, что делать надо TUI. Следует, что клавиатурная навигация во многих GUI сделана плохо.
Ничто не мешает графическому приложению управляться с клавиатуры так же полно, как терминальному, и лучше. Руководства по интерфейсам это прямо требуют: в GNOME Human Interface Guidelines написано, что всякое действие, выполнимое указателем, должно быть выполнимо и с клавиатуры, и что по любой части интерфейса нужно уметь пройти без мыши. Рекомендация есть, соблюдают её выборочно.
Сам автор — тяжёлый пользователь терминала и от TUI не отговаривает. Его претензия к рассуждению: клавиатурность зависит от того, как написана программа, и средой не задаётся.
@prog_stuff
Переписать с нуля — один из семи вариантов, и обычно худший
Легаси-сервис годами просто работает, потом одна старая зависимость тянет за собой другую, тесты начинают падать, и мелкий баг кладёт всё приложение. Первый порыв всегда один: переписать. Итог порыва тоже известен — месяцы без новых функций и никакой гарантии, что новая версия окажется лучше старой.
В разборе семь стратегий модернизации и ситуации под каждую: оставить как есть, заранее договорившись, какое событие станет сигналом к переделке; вывести ненужный модуль из эксплуатации; обновить стек без смены архитектуры; перенести на другую платформу; заменить готовым продуктом; рефакторить по частям; переписывать постепенно по схеме Strangler Fig, когда новая система оплетает монолит и забирает его задачи модуль за модулем.
Главная мысль: одной системе не обязан подходить один подход. Стабильный модуль не трогают, забытую интеграцию удаляют, авторизацию выносят постепенно. Перед тем как предлагать переписывание, каждый кусок сверяют по шести критериям: как часто меняется, сколько ест поддержки, от чего зависит, есть ли тесты, сколько может лежать и остались ли люди, которые его понимают.
В нашем канале Tproger разобрали подробнее.
@prog_stuff
Легаси-сервис годами просто работает, потом одна старая зависимость тянет за собой другую, тесты начинают падать, и мелкий баг кладёт всё приложение. Первый порыв всегда один: переписать. Итог порыва тоже известен — месяцы без новых функций и никакой гарантии, что новая версия окажется лучше старой.
В разборе семь стратегий модернизации и ситуации под каждую: оставить как есть, заранее договорившись, какое событие станет сигналом к переделке; вывести ненужный модуль из эксплуатации; обновить стек без смены архитектуры; перенести на другую платформу; заменить готовым продуктом; рефакторить по частям; переписывать постепенно по схеме Strangler Fig, когда новая система оплетает монолит и забирает его задачи модуль за модулем.
Главная мысль: одной системе не обязан подходить один подход. Стабильный модуль не трогают, забытую интеграцию удаляют, авторизацию выносят постепенно. Перед тем как предлагать переписывание, каждый кусок сверяют по шести критериям: как часто меняется, сколько ест поддержки, от чего зависит, есть ли тесты, сколько может лежать и остались ли люди, которые его понимают.
В нашем канале Tproger разобрали подробнее.
@prog_stuff
Samsung встроила вычислительные блоки прямо в LPDDR5X
Samsung продолжила линию Processing-in-Memory: в
Устройство напоминает жёстко ограниченный SIMD: одна операция и один операнд распространяются на все 16 банков. Их суммарная внутренняя пропускная способность достигает 614 ГБ/с, тогда как обычное обращение к памяти через внешнюю шину упирается в 76,8 ГБ/с.
Каждый PIM-блок держит четыре операции MAC в INT8 или FP8 за такт данных, то есть восемь за такт без учёта удвоенной передачи. На четырёхбитных весах пропускная способность удваивается, и пакет выдаёт 2,4 TOPS. Восемь чипов дают 9,6 INT8 TOPS, как NPU Intel Meteor Lake, и требуют 128 ГБ системной памяти. Архитектуру разобрали по материалам Hot Chips 2026.
@prog_stuff
Samsung продолжила линию Processing-in-Memory: в
LPDDR5X-9600 у каждого из 16 банков появился PIM-блок с MAC-деревом, регистрами инструкций и векторов активаций. Память выполняет часть вычислений там, где лежат данные, и работает через стандартный протокол LPDDR5X. Особые адреса строк включают режимы по принципу MMIO-регистров.Устройство напоминает жёстко ограниченный SIMD: одна операция и один операнд распространяются на все 16 банков. Их суммарная внутренняя пропускная способность достигает 614 ГБ/с, тогда как обычное обращение к памяти через внешнюю шину упирается в 76,8 ГБ/с.
Каждый PIM-блок держит четыре операции MAC в INT8 или FP8 за такт данных, то есть восемь за такт без учёта удвоенной передачи. На четырёхбитных весах пропускная способность удваивается, и пакет выдаёт 2,4 TOPS. Восемь чипов дают 9,6 INT8 TOPS, как NPU Intel Meteor Lake, и требуют 128 ГБ системной памяти. Архитектуру разобрали по материалам Hot Chips 2026.
@prog_stuff
🤯1