Aggregate lowering — первое исследование
Исследование и кандидат оптимизации, не универсальная гарантия скорости.
Baseline PR #19 слит отдельно (77610b4), исходный baseline b320611 не менялся.
JSON-парсер также не менялся. Измерение: Apple M4, 16 ГиБ, Apple Clang 21,
O2, generic CPU, тот же корпус и чанки 2048 байта. Кандидат: 7c1da5d.
Изоляция изменений
| Вариант | Что проверяет |
|---|---|
| A0 | Исходный компилятор b320611, повторно измеренный на том же стенде |
| A1 | Только readonly/nocapture/noalias-аннотации ABI для JsonState; не перебор всех возможных ABI |
| A2 | Локальное переиспользование временных значений и stack slots в ациклических функциях |
| A3 | Специализация целого состояния при доказанном отсутствии старых наблюдателей |
A1/A2 включаются только исследовательским emitter. В рабочий backend добавлен только A3. Semantic IR всех вариантов совпадает; различается физическое lowering.
Медиана throughput ядра, МиБ/с
По 10 повторов на вариант и нагрузку, всего 240 сырых измерений. Больше — быстрее.
| Нагрузка | A0 | A1 | A2 | A3 | A3/A0 |
|---|---|---|---|---|---|
| ascii | 42.88 | 42.39 | 38.64 | 71.77 | 1.67× |
| depth64 | 29.76 | 29.75 | 26.64 | 49.33 | 1.66× |
| escaped | 55.18 | 56.06 | 43.29 | 88.23 | 1.60× |
| long-string | 64.50 | 63.49 | 60.94 | 118.51 | 1.84× |
| numbers | 38.96 | 39.53 | 38.56 | 99.70 | 2.56× |
| unicode | 55.59 | 54.65 | 52.40 | 95.20 | 1.71× |
A1 не дал существенного ускорения. A2 уменьшил frame, но не улучшил скорость. Это подтверждает необходимость измерять горячий путь: размер frame и количество статических memcpy сами по себе не определяют стоимость исполнения.
Динамические bulk-copy и stack frame
На ASCII диагностическая сборка подсчитала объём выполненных memcpy/memmove в оптимизированном IR на входной байт:
| A0 | A1 | A2 | A3 |
|---|---|---|---|
| 720.53 | 717.53 | 772.63 | 256.13 |
Это не все машинные копирования: scalarized stores и перемещения регистров не учитываются. Счётчики вставлены после O2; отдельная диагностическая сборка не участвует в измерении времени. Учитываются также bridge, init и finish.
Для горячей specialized-функции __liza_owned___liza_json_step frame составляет
720 байт вместо 4480 байт исходной функции. Обычная immutable-версия сохраняется
для случаев, где уникальность не установлена; её frame в кандидате — 3696 байт.
Frame json.feed уменьшился с 608 до 416 байт. Это размеры отдельных функций,
не оценка максимального стека цепочки вызовов.
Почему снимки остаются независимыми
Публичный ABI по-прежнему передаёт большие значения через immutable storage.
Дополнительный callee используется только если caller доказал отсутствие живого
наблюдателя исходного allocation, включая копии, проекции и views. Сам move
не является доказательством уникальности; входной параметр caller не считается
его эксклюзивным allocation.
Новая форма специализации ограничена ациклической функцией с одним большим аргументом и результатом того же типа. Все возвраты должны происходить от этого аргумента через проверенные обновления, phi или уже доказанный direct-callee. Каждый разрушающий переход проверяет отсутствие старых наблюдателей; второй аргумент вызова не может наблюдать обновляемый корень. Композиция строится снизу вверх; рекурсивная группа не может объявить собственную сводку доказанной. Readonly-параметры и функции с View-параметрами исключены. Циклические callee остаются на обычном ABI; caller с циклом может использовать доказанный callee.
Проверки арифметики и границ не удаляются. Существующая специализация функций, возвращающих входное значение первым полем обёртки, сохраняется отдельно.
Проверки и граница результата
- 351 локальный тест компилятора: успешно, 11 платформенных пропусков.
- 202 теста Verified: успешно; это регрессии прежних доказательных фрагментов.
- 7 новых тестов: цепочки вызовов, порядок обнаружения сводок, публичный ABI, snapshot/view, bounds и overflow при O0/O2.
- Мутация liveness принимает destructive call при живом snapshot:
snapshot(3)возвращает ошибку 1 вместо 0 в конкретном нативном replay. - Мутация overflow-guard позволяет
trap(255)завершиться нормально вместо trap; контроль обнаруживает нарушение при O0/O2. - A0–A3 совпадают на 6785 разбиениях и 615 CLI-проверках до измерения.
Это не формальное доказательство soundness storage analysis и не проверка всех машинных программ. Достигнут выигрыш на шести выбранных нагрузках; глубоко вложенный JSON всё ещё ниже ориентира 70 МиБ/с. Рубежи 150/300 МиБ/с не достигнуты. T2-B и дальнейшая работа над lowering остаются самостоятельными этапами.
Исходники исследования — benchmarks/aggregate/. Сырые измерения, команды,
версии, хеши, counters и stack records сохранены в results/apple-m4/report.json.
Архив evidence.tar.gz содержит IR/assembly; manifest.json фиксирует его хеши.
Полные snapshots и бинарники остаются в каталоге локального запуска и
воспроизводятся по указанным коммитам. Никакие старые отчёты не переписаны.