Becoming a compiler engineer 🔥 Горячее
—
Комментарии (125)
- Комментарии разделены на два лагеря: одни считают, что статья — это личный пиар, другие — что она может быть полезна как ориентир для тех, кто хочет попробовать себя в этой области.
- Участники обсуждают, что вакансии в этой области редки, и что большинство компаний предпочитают нанимать специалистов по контракту, а не держать штатных сотрудников.
- Некоторые участники подчеркивают, что важно не только знание теории, но и практический опыт с LLVM, и что это может быть решающим фактором при найме.
- Обсуждается, что вместо того, чтобы писать статьи о "как стать компилятором", лучше было бы написать практическое руководство по созданию компилятора.
- Участники также обсуждают, что вместо того, чтобы писать статьи о "как стать компилятором", лучше было бы написать практическое руководство по созданию компилятора.
Why SSA Compilers?
SSA (Static Single Assignment) — это популярная форма промежуточного представления, используемая в большинстве современных компиляторов, включая LLVM, GCC, V8 и HotSpot. Её главная сила — в упрощении анализа и оптимизации программ. SSA преобразует императивный код с изменяемыми переменными в форму, где каждая переменная присваивается только один раз, что делает зависимости между значениями явными и легко отслеживаемыми.
Эта трансформация превращает программы с состоянием в комбинационные схемы без памяти, значительно упрощая оптимизации. Вместо отслеживания изменений переменных по всему коду компилятор может работать с чётко определёнными зависимостями. Например, программа с множественными присваиваниями одной переменной преобразуется в несколько переменных, каждая из которых имеет одно назначение, что позволяет легко находить и устранять избыточные вычисления.
Комментарии (84)
- Обсуждение разошлось в сторону: от обсуждения SSA как формы IR и её влияния на оптимизации, к дискуссии о том, что такое SSA, как она соотносится с CPS и какие у неё есть trade-off'ы, а также к тому, что именно делает SSA «особенной» и как она влияет на компиляторы и языки.
GNU Octave Meets JupyterLite: Compute Anywhere, Anytime
Команда Jupyter представила Xeus-Octave - новый kernel для JupyterLite, позволяющий запускать GNU Octave прямо в браузере. GNU Octave - бесплатный аналог MATLAB, теперь доступный без установки благодаря компиляции в WebAssembly. Для решения технических вызовов потребовался специальный инструмент на базе LLVM Flang и Emscripten для компиляции Fortran-кода, а также реализация BLAS/LAPACK, где выбор пал на Netlib LAPACK из-за меньших сложностей сборки.
Ключевым препятствием стало обширное использование блоков общих символов Fortran во внутренних библиотеках Octave, таких как odepack. Версия LLVM v20 на момент тестирования не поддерживала общую символьную линковку для WebAssembly, что потребовало дополнительных усилий для преодоления этого ограничения.
Комментарии (39)
- JupyterLite позволяет в браузере запускать ядра C++, Python, R, Lua, JavaScript и др. без серверной части.
- Octave и MATLAB — это два разных инструмента, и хотя Octave стремится к совместимости, он не является «клоном» MATLAB.
- Сообщество подчеркивает, что Octave — это полноценный язык для численных вычислений, а не просто «бесплатная замена MATLAB».
- Пользователи отмечают, что Octave и MATLAB различаются в деталях, но для базовых задач они взаимозаменимы.
- Обсуждение подняло вопрос о том, что Octave может быть полезен как встраиваемая библиотека, но это требует дополнительной работы.
Next steps for BPF support in the GNU toolchain
Крупные компании, включая Google и Meta, вкладываются в развитие BPF для Linux, чтобы ускорить обработку сетевых пакетов и улучшить безопасность. Теперь инструментарий GCC тоже получает поддержку BPF, что расширяет возможности компиляторов для этой технологии.
Основное внимание уделяется интеграции BTF (формат типа BPF) и CTF (компактный формат типа C), которые позволяют эффективно работать с типами данных в BPF. Это важно, чтобы обеспечить совместимость и оптимизацию. В GCC добавлены атрибуты btf_decl_tag и btf_type_tag, которые помогают аннотировать код для лучшей проверки и безопасности.
Эти усилия направлены на то, чтобы GCC могла стать полноценной альтернативой существующим инструментам для BPF, таким как LLVM, что особенно важно для встраивания BPF в различные среды и системы. Работа также включает улучшения в тестировании и отладке, чтобы обеспечить надежность.
Комментарии (18)
- Обсуждение вращается вокруг лицензии LLVM и Apache 2.0, их совместимости с GPL и влияния на свободное ПО.
- Участники спорят о том, что означает «свободное ПО» и какие лицензии считаются «свободными» в 2024 году.
- Обсуждается, что означает «свободное ПО» и какие лицензии считаются «свободными» в 2024 году.
- Участники обсуждают, что такое «свободное ПО» и какие лицензии считаются «свободными» в 2024 году.
The reason GCC is not a library (2000)
Ричард Столлман выступает против превращения GCC бэкенда в библиотеку, аргументируя это защитой свободного программного обеспечения. Он предупреждает, что компании неизменно стремятся сделать ПО несвободным, и некоторые создали бы несвободные дополнения к GCC, если бы им это позволили. Именно требование GPL заставило авторы фронтендов для C++ и Objective-C сделать их свободными, так как они не могли использовать их иначе. Столлман подчеркивает: "Все, что упрощает использование GCC бэкендов без фронтендов, ставит под угрозу наше влияние на то, чтобы новые фронтенды оставались свободными".
Проект GNU с высокой вероятностью не примет такие изменения, если они появятся, и это "твердый вывод, основанный на десятилетии размышлений". Столлман приглашает всех заинтересованных лиц связаться с ним лично для обсуждения их идей, потенциальной пользы и альтернативных подходов, призывая задуматься о важности будущих свободных фронтендов и интересов проекта в целом.
Комментарии (87)
- Пропущенное предложение интегрировать LLVM в GCC стало ключевым событием в истории компиляторов, но оно было упущено из-за сбоя в почтовой переписке.
- Это стало причиной того, что LLVM вместо того, чтобы стать частью GCC, стал основой для большинства новых языков и проектов.
- Парадокс в том, что GCC и LLVM сегодня по сути предлагают одинаковую производительность, но LLVM лицензирован более свободно, что способствует его популярности.
- В то же время, GCC остаётся под GPL, что отталкивает некоторых разработчиков, которые не хотят, чтобы их код был связан с GPL.
- В конечном счёте, это привело к тому, что LLVM стал основой для большинства новых языков программирования, в то время как GCC медленно движется к облесению.
Zig builds are getting faster 🔥 Горячее 💬 Длинная дискуссия
Компиляция Zig становится значительно быстрее благодаря многолетней работе над оптимизацией компилятора. Например, сборка скрипта build.zig в версии 0.15 заняла всего 1,7 секунды против 7,2 секунд в версии 0.14. Полная сборка проекта Ghostty без кеша сократилась с 41 до 32 секунд, даже с использованием LLVM.
Особенно впечатляет скорость инкрементных сборок: пересборка библиотеки libghostty-vt после изменения одной строки теперь занимает менее секунды (975 мс против 2,9 секунд ранее). Это уже ощутимо ускоряет рабочий процесс, а в будущем, с отказом от LLVM и внедрением инкрементной компиляции, результаты станут ещё лучше — ожидаются миллисекундные задержки.
Комментарии (190)
- LLVM рассматривается как ловушка из-за сложности тонкой настройки финальных оптимизаций и линковки, несмотря на преимущества в скорости начальной разработки и поддержке платформ. Cranelift и другие бэкенды могут стать альтернативой.
- Zig фокусируется на скорости компиляции для разработки, используя собственный бэкенд для debug-сборок (x86_64) и LLVM для релизов. Есть баги, но инструментарий ценится за простую кросс-компиляцию и статическую линковку.
- Быстрая компиляция (TCC, Go, Vlang) важна для итеративной разработки, но trade-off с оптимизацией кода неизбежен. Интерпретаторы или JIT-компиляция (Julia) предлагают альтернативы для интерактивности.
- Интеграция Zig с системами сборки (Bazel) возможна через правила, но Turing-полные скрипты сборки могут усложнить кеширование. Библиотеки часто обходятся без кастомных скриптов.
- Поддержка платформ (OpenBSD) требует доработки низкоуровневого IO (kqueue). Статическая линковка зависимостей в Zig упрощает деплой, но динамические библиотеки (libc, GUI) остаются.
From Rust to reality: The hidden journey of fetch_max
В Rust есть встроенная атомарная операция fetch_max, которая отсутствует в Java и C++. Она позволяет безопасно обновлять максимальное значение в многопоточной среде без явного написания цикла CAS. Исследование показало, что fetch_max генерируется макросом atomic_int! в стандартной библиотеке Rust, который создаёт методы для атомарных типов.
На уровне компиляции LLVM эта операция превращается в цикл сравнения и обмена, скрытый от программиста. Это демонстрирует, как Rust абстрагирует сложные низкоуровневые детали, предоставляя удобные и безопасные примитивы для конкурентного программирования.
Комментарии (49)
- Автор обнаружил, что Rust имеет встроенную атомарную операцию
fetch_max, которой нет в Java и C++ (хотя она планируется в C++26). - Обсуждение затронуло технические детали реализации атомарных операций (например, на ARM и x86), их производительность при высоком уровне конкуренции и возможность компилятором оптимизировать циклы CAS в нативные инструкции.
- Участники отметили, что подобные низкоуровневые операции существуют и в других средах, таких как GPU (HLSL/GLSL/CUDA) и RISC-V.
- Многие выразили признательность автору за познавательную статью, углубившую их понимание модели памяти и атомарных операций.
- Несколько человек поинтересовались, был ли нанят кандидат, упомянутый в исходной статье, на что автор ответил, что тот не подошел по культуре.
Apple Silicon GPU Support in Mojo
Mojo теперь поддерживает программирование GPU на Apple Silicon, что делает разработку GPU-ускоренных алгоритмов и AI-моделей доступнее для владельцев современных Mac. Для работы требуется macOS 15, Xcode 16 и чипы M1–M4. Пока функциональность ограничена: не работают сложные примеры вроде матричного умножения, AI-модели, PyTorch-интеграция и некоторые аппаратные возможности. Планируется доработка поддержки atomic operations, bfloat16 и других функций.
Технически код компилируется в AIR bitcode через LLVM IR, затем в .metallib через Metal-cpp API, скрыто от разработчика. Существующий код для NVIDIA/AMD GPU должен работать, но для максимальной производительности потребуются оптимизации под архитектуру Apple. Документация и открытый вклад ожидаются позже, когда базовая инфраструктура будет стабилизирована.
Комментарии (40)
- Обсуждение касается языка Mojo и его потенциала в области глубокого обучения и GPU-программирования, с акцентом на его совместимость с экосистемой Python и производительность.
- Участники спорят о нишевости написания кастомных CUDA/Triton ядер, отмечая, что это сложно и этим занимаются немногие, но Mojo может сделать этот процесс более доступным.
- Высказываются как скептические мнения о будущем Mojo (называя его "проектом тщеславия"), так и оптимистичные, видящие в нём важный прорыв и альтернативу существующим инструментам.
- Поднимаются вопросы о бизнес-модели Mojo (лицензирование) и её потенциальном влиянии на открытость экосистемы, что может отпугнуть часть разработчиков.
- Отмечается, что синтаксис Mojo, основанный на Python, является его сильной стороной для привлечения аудитории data scientists, но сама языковая модель и runtime отличаются.
Titania Programming Language
Titania — экспериментальный язык от автора Odin.
Цель: максимум производительности, минимум «магии», ясный код.
Ключевые идеи
- Статическая типизация, компиляция «в ноль»
- Нет GC: ручной или автоматический RAII
- Процедурный, но с мощными шаблонами и compile-time вычислениями
- Прямая работа с SIMD, FFI, встраиваемый ASM
- Синтаксис: C-подобный, но короче; нет препроцессора
Статус
Публичный прототип, API меняется. Собирается LLVM или собственный бэкэнд.
Комментарии (42)
- Участники обсуждают язык Wirthwhile: критикуют обязательное объявление всех переменных в начале функции, но @munificent объясняет, что это упрощает однопроходную компиляцию.
- Появляются вопросы о мотивации создания ещё одного языка и его отличиях от Oberon-07; @khaledh напоминает, что автор — создатель Odin.
- Предлагаются экспериментальные синтаксические идеи: спец-символ «.» для перевода строки и отказ от println; сообщество отмечает конфликт с методами и контекстно-зависимость грамматики.
PythonBPF – Writing eBPF Programs in Pure Python
PythonBPF – пишем eBPF-программы на чистом Python
(в 2 раза короче)
Что это
Библиотека pip install pythonbpf компилирует Python-код в объектные .o-файлы и загружает их в ядро как обычные eBPF-программы. Репо: GitHub.
Было
Встраивали C в многострочные строки, теряя линтеры и подсветку:
from bcc import BPF
prog = """
int hello(void *ctx) {
bpf_trace_printk("Hello\\n");
return 0;
}
"""
b = BPF(text=prog)
b.attach_kprobe(event="sys_clone", fn_name="hello")
Стало
Тот же функционал — на Python:
from pythonbpf import bpf, section, compile
from pythonbpf.maps import HashMap
from pythonbpf.helpers import ktime
from ctypes import *
@bpf
def last() -> HashMap: # глобальная BPF-мапа
return HashMap(c_uint64, c_uint64, 1)
@bpf
@section("tracepoint/syscalls/sys_enter_execve")
def hello(_: c_void_p) -> c_int32:
print("entered")
return 0
@bpf
@section("tracepoint/syscalls/sys_exit_execve")
def bye(_: c_void_p) -> c_int64:
print("exited")
last().update(0, ktime())
return 0
@bpf
def LICENSE() -> str: # лицензия ядра
return "GPL"
compile() # → .o и загрузка
Как работает
ast→ деревоllvmlite→ LLVM IRllc→ BPF-объектlibbpf→ загрузка в ядро
Комментарии (28)
- Участники обсуждают инструмент для компиляции Python в eBPF байт-код, который был создан как проект на хакатоне и пока считается «игрушечным».
- Подчеркивается, что использование LLVM для трансляции в eBPF — более перспективный подход, чем прямое преобразование Python-байткода.
- Несколько пользователей отмечают отсутствие четких объяснений, что такое eBPF, и предлагают добавить больше документации и примеров.
- Критикуется идея использования LLM (больших языковых моделей) для генерации eBPF-кода из-за строгой проверки и специфики eBPF.
- Упоминаются существующие аналогичные проекты для других языков (Java, Node.js) и инструменты из мира BCC.
- Автор проекта признает, что код находится на ранней стадии и требует значительной доработки.
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 проще и быстрее полной сортировки; эксперимент ставит границы, а не решает продакшен-задачу.
ML needs a new programming language – Interview with Chris Lattner 🔥 Горячее 💬 Длинная дискуссия
- Крис Латтнер (LLVM, Swift) делает новый язык Mojo, чтобы ML-код был быстрым и удобным.
- Проблема: GPU-ядра пишутся на CUDA/OpenCL вручную, медленно и зависят от одного вендора.
- Решение: язык с метапрограммированием и типами, который «знает» об аппаратуре и генерирует оптимальный код под любую платформу.
- Цель: один код → любой GPU/CPU, открытая экосистема, no lock-in.
Комментарии (255)
- Mojo обещает «Python++, но быстрый», но до сих пор нет полноценных классов, а «полный суперсет» превратился в мягкое «всё ещё не Python».
- Лицензия проприетарная — для многих это стоп-фактор: «сделайте GPL или идите лесом».
- Экосистема Python неподвластна: все уже завязаны на PyTorch/CUDA, а Mojo пока не даёт причин мигрировать.
- Julia, Elixir/Nx, CuPy, Triton, Numba — всё уже умеют «быстро + GPU», без нового языка.
- Итог: Mojo выглядит технически интересным, но «ещё один закрытый язык» в 2025 году воспринимается как ненужный риск.
Fil's Unbelievable Garbage Collector 🔥 Горячее 💬 Длинная дискуссия
Fil-C — это C/C++-совместимый язык с безопасной памятью и современным инструментарием. Его сердце — FUGC, параллельный, конкурентный, точный, неперемещающий сборщик мусора.
Ключевые черты FUGC
- Параллельность: маркировка и очистка выполняются на всех ядрах.
- Конкурентность: потоки-мутаторы не останавливаются; блокировки только на медленных путях аллокации.
- On-the-fly: нет глобальной паузы; «мягкие рукопожатия» просят потоки асинхронно сканировать стек.
- Grey-stack: повторное сканирование стеков до фикс-поинта; барьер только при записи, быстрая сходимость.
- Dijkstra-barrier: при записи указателя объект помечается CAS-relaxed.
- Точность: LLVM-плагин
FilPizlonatorточно знает, где все указатели. - Неперемещаемость: объекты не двигаются; освобождённые блоки «перенаправляются» через InvisiCap.
Safepoint-механизм
- Компилятор вставляет
pollcheck: быстрая проверка или колбэк для GC. - «Мягкое рукопожатие» запускает колбэк на всех потоках.
- Состояния enter/exit позволяют блокироваться в syscall без pollcheck’ов; GC сам выполняет колбэк для «exited» потоков.
- Safepoint защищает от гонок: загруженный указатель будет жив до следующего safepoint’а.
По желанию можно включить полный stop-the-world (FUGC_STW=1) для fork(2) или отладки.
Комментарии (247)
- Fil-C — это С-компилятор с точным параллельным GC (FUGC) и capability-указателями, позволяющий запускать «как есть» CPython, SQLite, OpenSSH и др., теряя в худшем случае 4× производительности.
- Вместо ручного free и UB-оптимизаций LLVM код живёт под барьером Дейкстры и soft-handshake safepoint’ами; указатели превращаются в «InvisiCap» (base+offset), теряющие силу при приведении к integer.
- Проект исследовательский, но уже промышленно полезен: нет сборок под 32-бит, Windows и embedded без MMU, нет пока поколенческого GC и ARM/RISC-V.
- Споры: «lock-and-key» предсказуемее RAM, но требует атомиков; GC = «мусор потом» vs compile-time проверки; можно ли дождаться AI-стат-анализа вместо Rust-переписей.
How is Ultrassembler so fast?
Ultrassembler — библиотека RISC-V-ассемблера, встроенная в проект Chata.
В отличие от as и llvm-mc, она вызывается прямо из C++, без system() и временных файлов, что критично для встроенных систем.
Скорость
Тест на 16 тыс. инструкций:
- Ultrassembler ≈ 10× быстрее
as, 20× быстрееllvm-mc. - 1 RISC-V инструкция ≈ 1000 x86-инструкций (у конкурентов 10–20 тыс.).
Код на чистом C++; можно добавить ассемблерные вставки.
Ключевые оптимизации
Исключения
GCC-реализация «zero-overhead»: штрафа нет, пока исключений нет.
Ошибки встречаются редко и видны человеку, поэтому даже 1 с на обработку незаметна.
std::expected дал −10 %, так как нормальный путь стал дороже.
Быстрые структуры
2000+ RISC-V-инструкций требуют мгновенного поиска.
Вместо std::unordered_map используется perfect-hash таблица от gperf, генерирующая O(1) без коллизий.
Размер таблицы компактен, кэш-эффективен.
Парсинг
- Регистры идентифицируются по первым 2–3 символам через
switch. - Нет
std::string, толькоstd::string_viewи статические буферы. - Лексемы разбираются за один проход без регулярных выражений.
Кодогенерация
- Шаблоны на этапе компиляции формируют битовые маски инструкций.
- Варианты одной инструкции разворачиваются в
constexpr-таблицы, что убирает ветвления в рантайме.
Память
- Все выделения через стековые
std::array/std::string_view. - Нет
new/malloc, следовательно, нет аллокационных штрафов и кэш-промахов.
Платформенные трюки
[[likely]]/[[unlikely]]для подсказок ветвления.__builtin_expectтам, где компилятор не догадывается.- LTO + PGO дают ещё 5–7 %.
Итог
Ultrassembler показывает, что «низкоуровневый» C++ без искусственных ограничений может обгонять даже оптимизированные GNU-утилиты.
Комментарии (34)
- В обсуждении разобрали миф о «системном вызове при каждом росте контейнера» — реальные аллокаторы переиспользуют память и делают syscall лишь при нехватке.
- Участники напомнили, что исключения в C++ не «zero-overhead»; есть компромисс между временем и памятью, и g++ выбирает экономию места.
- Автор статьи подтвердил: пробовал хеширование, но дерево разбора оказалось быстрее; flex/bison тут не при чём, скорее gperf.
- Некоторые посоветовали LLVM C++ API, memory-mapped I/O и std::pmr для ускорения и упрощения кода.
- Большинство сходится: современные ассемблеры и так быстрые, задача скорее академическая, но как «посмотреть, насколько можно ускорить» — интересна.
10-20x Faster LLVM -O0 Back-End (2020)
TPDE-LLVM — новый бэкенд LLVM-O0, который в 10–20 раз быстрее стандартного, при сопоставимой скорости выполнения и росте кода на 10–30 %. Работает с IR Clang-O0/O1, цели x86-64 и AArch64.
Данные SPEC CPU 2017 (x86-64, ускорение компиляции и размер кода относительно LLVM 19 -O0):
| бенчмарк | O0 IR | O1 IR |
|---|---|---|
| perl | 11.4× / 1.27× | 15.1× / 0.97× |
| gcc | 12.5× / 1.32× | 17.6× / 1.01× |
| omnetpp | 21.5× / 1.24× | 26.5× / 1.03× |
| геом.ср. | 13.3× / 1.27× | 17.6× / 0.97× |
Как работает: три прохода — очистка IR, анализ (циклы + liveness), единый codegen (lowering, регистры, кодирование).
Поддержка: как библиотека, llc-подобный инструмент, патч для Clang. DWARF и улучшенный рег-аллокатор в планах.
Ограничения: не все IR-конструкции, векторы, TLS-глобалы, i260 и т.д.
Что ускорило бы LLVM ещё сильнее:
- убрать
ConstantExprвнутри функций; - запретить гигантские структуры/массивы как значения;
- упростить доступ к TLS и произвольную битовую арифметику.
Комментарии (6)
- Пользователи обсудили, что Gentoo всё ещё используют с флагом -O8 для максимальной производительности.
- Кто-то спросил, нужно ли добавить пометку «(2020)» к цитируемому тексту.
- Упомянули, что «все» якобы перешли на Arch, где компилятор якобы умеет -O11.
- Уточнили: пост 2025 года, но он цитирует запись 2020-го; попросили модератора исправить.
TPDE-LLVM: Faster LLVM -O0 Back-End
TPDE-LLVM: 10-20× быстрее -O0
Новый open-source бэкенд TPDE-LLVM ускоряет компиляцию в режиме -O0 в 10–20 раз при сопоставимой скорости выполнения и увеличении кода на 10–30 %. Поддерживаются x86-64 и AArch64, типичное IR Clang O0/O1.
| SPEC 2017 (x86-64) | Ускорение | Размер |
|---|---|---|
| perl | 11.4× | 1.27× |
| gcc | 12.5× | 1.32× |
| mcf | 9.7× | 1.27× |
| omnetpp | 21.5× | 1.24× |
| xalanc | 19.0× | 1.24× |
| x264 | 10.5× | 1.26× |
| deepsjeng | 9.6× | 1.25× |
| leela | 21.4× | 1.24× |
| xz | 11.0× | 1.30× |
| geomean | 13.3× | 1.27× |
Как работает
Три прохода: очистка IR, анализ (циклы + живость), кодогенерация (lowering, регистры, код) за один проход. Подробности — в статье.
Планы
- DWARF, улучшенный регистровый аллокатор.
- Поддержка Flang/Rust неполная (векторы, FP-операции).
- Нет non-ELF, других целей.
Использование
Библиотека, llc-подобный инструмент, патч для Clang.
Почему не ускорить LLVM?
LLVM 18→20 стал быстрее на 18 %, но 10× требует радикальных изменений.
Что мешает ещё быстрее
ConstantExprвнутри функций.- Структуры/массивы произвольного размера.
- Прямой доступ к TLS-глобалам.
- Арифметика произвольной битности (
i260).
Факты
- 4 байта padding в
Instructionдля служебных номеров. PHINode::getIncomingValForBlockквадратичен при >1 k предков.- 90 % времени
tpde-llc— парсинг биткода.
Комментарии (56)
- TPDE — новый бэкенд, генерирующий код на 10–20× быстрее LLVM, но чуть медленнее -O0.
- Участники спорят, насколько «парето-улучшение» реально: поддерживается лишь «типичное» подмножество LLVM-IR, векторные инструкции и экзотика не работают.
- Некоторые вспомнили Copy-and-Patch и другие подходы, где LLVM используется для библиотеки патчей, но теряется 2,5× в рантайме из-за регистров.
- Основная узкость теперь — фронтенды (rustc, Clang), которые даже при TPDE занимают >98 % времени сборки.
- Желают скорейшего переноса в Swift и Wasmer, но сомневаются в готовности сообщества LLVM что-то менять.
Show HN: Luminal – Open-source, search-based GPU compiler
luminal — библиотека для глубокого обучения, работающая «со скоростью света».
Основное
- Язык: Rust
- Цель: максимально быстрое вычисление градиентов и обучение нейросетей.
- Подход: компиляция вычислительного графа в высокооптимизированный нативный код (LLVM).
Возможности
- Автоматическое дифференцирование.
- JIT-компиляция графов.
- Поддержка CPU и GPU (CUDA).
- Минимальные накладные расходы: нет Python-интерпретатора и лишних библиотек.
Примеры
let x = Cpu::tensor([1.0, 2.0, 3.0]);
let y = x.relu().sum();
let g = y.backward(); // градиент за наносекунды
Установка
cargo add luminal
Статус
Проект в активной разработке; API может меняться.
Комментарии (53)
- Luminal — это ML-фреймворк, который вместо ручных правил формулирует оптимизацию как поиск по огромному пространству возможных ядер (tiling, потоки, инструкции и т.д.) с помощью e-graphs.
- Сейчас на M-серии MacBook Llama-3 8B Q8 выдаёт 15-25 ток/с; это ниже llama.cpp, но команда строит трекер производительности и продолжает улучшать поиск.
- Поиск ограничен 12 базовыми линейно-алгебраическими операциями, что делает задачу похожей на «superoptimisation» и позволяет добавлять аппаратно-специфичные инструкции (tensor cores, PTX/ASM) без роста frontend.
- Для оценки качества ядра используется реальное время выполнения на целевом железе; масштабировать планируют распараллеленным профилированием на кластерах GPU.
- Отличие от TVM/tinygrad — единое пространство поиска, включающее как параметры тайлинга, так и алгебраические преобразования (например, softmax → flash-attention).
I made a real-time C/C++/Rust build visualizer 🔥 Горячее
Я написал What the Fork — кроссплатформенный визуализатор сборки C/C++ (и не только).
Запуск: wtf make, wtf cargo build, wtf gradle build, wtf -x для Xcode и т.д.
Инструмент показывает все процессы, включая скрытые вызовы ld, и ищет типичные проблемы:
- отсутствие
-jуmake, - однопоточная компиляция,
- повторяющиеся cmake/make-шаги,
- непараллельные CI-сборки.
Как работает
Сборка = дерево команд. Чтобы увидеть всё, ловим системные вызовы fork/exec/exit:
- macOS — Endpoint Security API,
- Linux —
ptrace, - Windows — Event Tracing (самое мерзкое API).
Что уже нашли
- cargo собирал зависимость одним потоком вместо 10× ускорения.
- ninja при сборке LLVM держит 12 задач на 10 ядрах — почти идеал.
- CMake 85 раз подряд вызывает
xcode-select,sw_vers, cmake/make → clang, не используя параллелизм.
Инструмент открыт для тестов — попробуйте на своём проекте.
Комментарии (82)
- Пользователи восторженно реагируют на новый визуализатор сборки, особенно те, кто застрял на CMake/GCC/Make без clang/ninja и не может понять, почему сборка тормозит.
- Просят сразу показать GIF-демонстрацию под заголовком статьи и спрашивают, будет ли macOS-версия и открытый код.
- Некоторые делятся опытом: strace/dtruss, ninjatracing, vcperf, cargo --timings, Instruments и другие инструменты уже решали похожие задачи.
- Предложения расширить функциональность: добавить flame-графы процессов, поддержку fork(), интеграцию с Bazel Build Event Protocol, оценку «осталось времени» по историческим данным.
- Отдельные комментарии касаются маркетинга (сменить название), сравнения с VS/Xcode, а также шуток про TEEP/OEE завода и «LLVM, завари кофе».
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 потребуется дополнительная обработка переменной длины кодов.
Комментарии (54)
A really good accompaniment to this is Carruth's "C++, bounds checking, performance, and compilers" [1]:> ... strong belief that bounds checks couldn’t realistically be made cheap enough to enable by default. However, so far they are looking very affordable. From the above post,