The state of SIMD in Rust in 2025
В 2025 году SIMD в Rust продолжает развиваться, предлагая значительный прирост производительности до 64x для операций с u8 на современных процессорах. Основная проблема - фрагментация наборов инструкций: ARM использует обязательный NEON (128 бит), WebAssembly - 128-bit packed SIMD, а x86 имеет сложную иерархию от SSE2 до AVX-512 (512 бит). Для x86 разработчики выбирают между указанием target-cpu (например, x86-64-v3) и использованием function multiversioning для поддержки различных процессоров.
В Rust существует четыре подхода к SIMD: автоматическая векторизация (самый простой), продвинутые итераторы, портируемые абстракции и сырые интринсики. В то время как ARM стандартизировал NEON, а WebAssembly требует компиляции двух бинарных файлов, x86 остается самой сложной платформой из-за множества расширений и необходимости обеспечения обратной совместимости.
Комментарии (128)
- Обсуждение показало, что Rust пока не может предложить стабильный и удобный способ работы с SIMD, в отличие от C# и C++.
- Основная причина —
std::simdвсё ещё в nightly, а стабильная альтернатива отсутствует. - Участники также отметили, что даже в ночной ветке API нестабилен и может измениться, что делает его использование в production-окружениях проблематичным.
- Некоторые участники выразили обеспокоенность тем, что отсутствие стабильной SIMD-поддержки может отпугнуть потенциальных пользователей Rust, особенно в областях, где эффективное использование SIMD критично.
- В то же время, другие участники подчеркнули, что Rust всё ещё молодой язык и что сообщество может в конце концов решить эту проблему, как это было с другими функциями в прошлом.
86 GB/s bitpacking with ARM SIMD (single thread)
Проект демонстрирует технику оптимизации производительности через упаковку данных в байтовые структуры для минимизации памяти и ускорения обработки. Основная идея — использование примитивных типов и битовых операций вместо высокоуровневых структур, что особенно эффективно в системах с ограниченными ресурсами или требующих высокой пропускной способности.
В примерах показано, как сократить размер данных в 4–8 раз по сравнению с традиционными подходами, например упаковывая несколько булевых значений в один байт или используя битовые маски для хранения состояний. Это не только экономит память, но и улучшает производительность за счёт лучшей локализации данных и уменьшения аллокаций. Практический вывод: для критичных к производительности задач стоит рассматривать низкоуровневую оптимизацию данных, даже если она усложняет код.
Комментарии (24)
- Проблемы совместимости кода для x86 и ARM архитектур, включая необходимость использования библиотеки SIMDe для эмуляции x86 intrinsics на ARM.
- Обсуждение особенностей и ограничений NEON (ARM SIMD) по сравнению с SSE (x86 SIMD), включая отсутствие инструкции movemask и предложенные альтернативы.
- Потенциальные применения алгоритма для эффективной битовой упаковки и распаковки данных в задачах, чувствительных к пропускной способности памяти (например, в data warehouses).
- Критика методологии бенчмарков и сравнений в исходном исследовании, анонс собственной работы по схожей тематике.
- Рекомендации к дополнительным материалам по теме: научная статья обобщающая алгоритмы и статья о симуляции bit packing на NEON.
How fast is Go? Simulating particles on a smart TV
Go позволяет эффективно симулировать миллионы частиц на сервере и транслировать результат клиентам в виде видео, избегая отправки данных каждой частицы. Ключевая идея — рендерить симуляцию на сервере и передавать клиентам только сжатые кадры, что делает нагрузку независимой от числа частиц и зависящей лишь от разрешения. Для HD-видео (1920×1080) несжатый кадр занимает ~2 МБ, но сжатие H264/H265 сокращает его до ~260 КБ, что при 24 кадрах в секунду близко к обычному видеопотоку.
Это выгоднее, чем отправлять данные частиц: даже при оптимизации (8 байт на частицу) миллион частиц потребует 8 МБ на кадр — в 4 раза больше, чем несжатое изображение. Такой подход обеспечивает совместимость с любыми устройствами, включая Smart TV, поскольку клиенту нужно лишь воспроизводить видео на canvas, без тяжёлых вычислений. Go справляется с этой задачей, демонстрируя производительность, достаточную для многопользовательских симуляций в реальном времени.
Комментарии (26)
- Обсуждаются сильные стороны Go: простота синтаксиса, поддержка больших кодовых баз, быстрая сборка и встроенные инструменты для тестирования и конкурентности.
- Отмечается слабая оптимизация Go для численных расчётов и вычислительных задач, выражается надежда на внедрение SIMD-инструкций в будущем.
- Предлагаются методы сжатия изображений для проекта, включая использование PNG и дельта-кодирования с RLE, а также улучшение сжатия через XOR нового и старого кадра.
- Критикуется использование Euler-интегрирования в симуляции частиц, автор признаёт упрощённый подход с учётом дельта-времени и трения.
- Упоминается, что эксперимент с пакетом
arenaдля управления памятью приостановлен из-за проблем с API, идёт поиск альтернативных решений.
Комментарии (47)
- Обсуждение лицензирования: проект использует Elastic License 2.0, что вызывает споры о его статусе как открытого или исходного кода, несмотря на бесплатное использование в open-source проектах.
- Технические аспекты поиска: обсуждается эффективность brute-force подхода с оптимизацией через SIMD, сравнение с индексированными методами (например, HNSW) и вопросы производительности при больших объемах данных.
- Использование товарных знаков: критикуется использование домена sqlite.ai и бренда SQLite без явной связи с авторами SQLite, что может вводить в заблуждение.
- Практические применения: векторные базы данных полезны для поиска схожих элементов (например, через эмбеддинги) в машинном обучении, обработке текстов и изображений.
- Альтернативы и сравнения: упоминаются другие решения, такие как sqlite-vec (с открытой лицензией) и Turso, а также обсуждаются их преимущества и недостатки.
UUIDv7 Comes to PostgreSQL 18
UUIDv7, новая версия универсального уникального идентификатора на основе временных меток, появится в PostgreSQL 18. Она решает ключевые проблемы традиционных UUID: отсутствие сортируемости и низкую локальность индексов. В отличие от UUIDv4 со случайной структурой, UUIDv7 содержит временной компонент, что обеспечивает последовательную вставку в B-деревья и снижает фрагментацию. Это особенно полезно для распределенных систем, где клиенты генерируют ID без координации с сервером.
Хотя размер UUID остаётся 128-битным (больше, чем INT или BIGINT), современные CPU эффективно обрабатывают такие значения через SIMD-инструкции. Важно использовать бинарное представление UUID, а не строковое, для оптимизации производительности. UUIDv7 также подходит для публичных идентификаторов, так как их сложно угадать, в отличие от автоинкрементных чисел. Это делает его идеальным выбором для шардированных баз данных и сред с минимальной серверной координацией.
Комментарии (42)
- Обсуждаются проблемы безопасности UUIDv7 из-за экспозиции времени создания в публичных идентификаторах, что может упростить угадывание соседних записей.
- Предлагаются решения для сокрытия времени создания на границе API, например, преобразование UUIDv7 в UUIDv4 или шифрование временной метки.
- Отмечается, что 62 бита случайности в UUIDv7 при наличии лимита запросов обеспечивают достаточную безопасность для большинства веб-приложений.
- Поднимается вопрос о негативном влиянии UUID (по сравнению с последовательными целыми числами) на производительность БД из-за отсутствия оптимизаций для последовательных ключей.
- Утверждается, что безопасность не должна зависеть от формата первичного ключа, а проблемы угадывания ID указывают на ошибки в проектировании системы.
Processing Strings 109x Faster Than Nvidia on H100
Выпущена StringZilla v4 — первая версия библиотеки для обработки строк с поддержкой CUDA, которая ускоряет вычисления на GPU. Она обеспечивает до 500 гигаопераций в секунду для расчёта расстояний Левенштейна и других метрик схожести строк, что в 109 раз быстрее решений на NVIDIA H100. Библиотека оптимизирована для больших объёмов данных в базах данных, биоинформатике и информационном поиске, включая алгоритмы с аффинными штрафами за разрывы и мини-хэширование.
Новые функции включают хэш-функции на основе AES, генераторы псевдослучайных строк и алгоритмы сортировки для работы с коллекциями строк. StringZilla использует SIMD-инструкции на CPU и GPU, поддерживает несколько архитектур и языков программирования. Библиотека распространяется под лицензией Apache 2.0 и доступна через pip, предлагая надёжный и быстрый базис для масштабируемых workloads.
Комментарии (23)
After publishing this a few days ago, 2 things have happened.First, it tuned out that StringZilla scales further to over 900 GigaCUPS around 1000-byte long inputs on Nvidia H100. Moreover, the same performance is obviously accessible on lower-end hardware as the algorithm is not
Titania Programming Language
Titania — экспериментальный язык от автора Odin.
Цель: максимум производительности, минимум «магии», ясный код.
Ключевые идеи
- Статическая типизация, компиляция «в ноль»
- Нет GC: ручной или автоматический RAII
- Процедурный, но с мощными шаблонами и compile-time вычислениями
- Прямая работа с SIMD, FFI, встраиваемый ASM
- Синтаксис: C-подобный, но короче; нет препроцессора
Статус
Публичный прототип, API меняется. Собирается LLVM или собственный бэкэнд.
Комментарии (42)
- Участники обсуждают язык Wirthwhile: критикуют обязательное объявление всех переменных в начале функции, но @munificent объясняет, что это упрощает однопроходную компиляцию.
- Появляются вопросы о мотивации создания ещё одного языка и его отличиях от Oberon-07; @khaledh напоминает, что автор — создатель Odin.
- Предлагаются экспериментальные синтаксические идеи: спец-символ «.» для перевода строки и отказ от println; сообщество отмечает конфликт с методами и контекстно-зависимость грамматики.
The unreasonable effectiveness of modern sort algorithms
Rust: «неразумная» скорость сортировки
- Сортировка в Rust быстрее C++ и Go благодаря LLVM, агрессивному векторизатору и ручным оптимизациям.
- Алгоритм: pdqsort (pattern-defeating quicksort) + векторизованный партиционер.
- Ключевые приёмы:
- 128-битные SIMD-операции (SSE/AVX) для фильтрации элементов;
- branchless-код, предикты, минимизация кэш-промахов;
- специализированные пути для малых типов (u8, u16, u32, u64, f32, f64) и копируемых структур;
- ручная развёртка циклов, инлайн, отказ от стандартных абстракций.
- Сравнение: на случайных u64 Rust ~2× быстрее libstdc++, ~3× быстрее Go; на почти отсортированных — ещё больше.
- Память: всё делается in-place, доп. буфер 1 КБ максимум.
- Сложность: O(n log n) в среднем, O(n log n) worst-case (pdqsort гарантирует).
- Код открыт, можно подсмотреть и перенести на другие языки.
Комментарии (38)
- Универсальный лайфхак: «сначала отсортируй данные» — и задача часто сводится к O(log n).
- Но глобальная сортировка дороже с ростом объёма; иногда проще пересмотреть подход или использовать хэш-таблицу.
- Современные unstable-sort и foldhash настолько быстры, что ручные оптимизации часто проигрывают и требуют лишней памяти.
- Для 4 уникальных значений подсчёт или perfect-hash проще и быстрее полной сортировки; эксперимент ставит границы, а не решает продакшен-задачу.
FFmpeg Assembly Language Lessons 🔥 Горячее
FFmpeg/asm-lessons — репозиторий с уроками по ассемблеру для FFmpeg.
Цель: научиться писать высокопроизводительные рутины на x86-64, ARM и других архитектурах, ориентированные на мультимедиа-задачи.
Содержание (кратко):
- Уроки: от базовых инструкций до векторных расширений (SSE/AVX, NEON).
- Примеры: реализация IDCT, фильтров, цветового преобразования.
- Тесты: юнит-тесты и бенчмарки для сравнения C vs asm.
- CI: автоматическая проверка на x86-64 и ARM через GitHub Actions.
Как начать:
- Клонируйте репо.
- Установите
nasm,yasmилиllvm-mingw. - Соберите пример:
make lesson01.
Полезные ссылки:
Комментарии (132)
- Пользователи восхищаются масштабом FFmpeg и экономией вычислений даже при небольших улучшениях.
- Обсуждаются случаи, когда ручная сборка быстрее intrinsic’ов, и инструменты для поиска «горячих точек».
- Некоторые ждали более глубокой связи с FFmpeg, а не общее введение в ассемблер.
- Поднимаются вопросы портативности (пока только x86-64), необходимости математических подготовок и перегруженности NASM-макросами.
- Большинство соглашается: писать LLVM IR вручную нет смысла, проще использовать inline-assembly или векторные инструкции.
Faster substring search with SIMD in Zig
SIMD-поиск подстроки в Zig
Автор реализовал алгоритм, который на 60 % быстрее std.mem.indexOf.
Идея: сравниваем 32-байтовые блоки текста с первым и последним символом искомого слова, используя AVX2.
- Берём первый и последний байт
needle(first,last). - Загружаем 32 байта
haystackв векторBlock = @Vector(32, u8). - Создаём маски совпадений:
const eq_first = first == block; const eq_last = last == block_shifted; const mask = @bitCast(eq_first & eq_last); - Для каждого установленного бита проверяем полное совпадение подстроки.
- Хвост обрабатываем обычным
indexOf.
Код (сокращённо):
const Block = @Vector(32, u8);
const first = @splat(needle[0]);
const last = @splat(needle[k-1]);
while (i + k + 32 <= n) : (i += 32) {
const f = haystack[i..][0..32].*;
const l = haystack[i+k-1..][0..32].*;
var mask: u32 = @bitCast((first == f) & (last == l));
while (mask != 0) {
const bit = @ctz(mask);
if (mem.eql(u8, haystack[i+bit+1..][0..k-1], needle[1..]))
return i + bit;
mask &= mask - 1;
}
}
return mem.indexOf(u8, haystack[i..], needle) orelse null;
Тест: поиск слова «newsletter» во всём «Моби Дике» (~1.2 МБ).
Сборка: zig build -Doptimize=ReleaseFast.
Комментарии (52)
- Подход с SIMD-ускорением поиска подстроки популярен, но в худшем случае остаётся квадратичным
O(m·n), поэтому нужен «откат» на линейный алгоритм (KMP/BM). - Участники отмечают, что большинство реализаций опираются на 10-летние AVX/NEON, игнорируя AVX-512, SVE и RVV, которые дают больший выигрыш, но пока редки на десктопах и в облаках.
- Zig пока не предоставляет прямых intrinsics, хотя LLVM-бекенд позволяет вызывать нужные инструкции; это тормозит портирование низкоуровневых оптимизаций.
- Есть идея дальнейшего SIMD-фильтра: проверять не только первый/последний байт иглы, но и второй/предпоследний и т.д., накладывая маски.
- Вопросы Unicode: алгоритм работает на байтах, поэтому для UTF-8/16 потребуется дополнительная обработка переменной длины кодов.