Профиль каскада плит ур.13 к.23: три рабочих документа по фазам
Контрольный замер перед оптимизацией (задача OPT-BLIT требовала начать с
него, а не с правок). Сцена: старт уровня 13, комната 23, шесть плит
сыплются с потолка вразнобой.
Пик логического кадра — 1 437 150 тактов при растровом кадре 430 000, то
есть 5-6 растровых кадров вместо трёх. По секциям (бюджет 400 000):
синяя 142 830 (в норме), зелёная до 805 000, циан до 632 000.
Что нашлось (всё подтверждено зондами, не гипотезы):
RDA_CEIL дрожащая плита-потолок 48 658 x до 6 = 292 000
RDA_CEIL_GONE запечь колодец 251 023 x до 2 = 619 000
RD_FLOOR щебень на месте посадки 198 259 x до 2 = 397 000
Внутри RDA_CEIL: heal 8 491 + draw_tile 39 029, а блитов в этом draw_tile
всего 1,17 на тайл (15-16 тыс.) — то есть ~23 700 тактов чистых накладных.
Подсчёт asm сходится до процентов: у draw_tile 26-байтовый стековый кадр и
513 обращений (ix), при ~46 замеренных тактах на обращение это те же
~23 600. У blit_b_clip — 22 Б кадра и 211 (ix).
Разбор одного pop_blit_b (157 замеров быстрого пути): atlas_image+w0_map
1 086, ядро libbgi 10 422, pop_cd_touch 4 502 (28%!), unmap+возврат 264.
В mob_render эти три pop_cd_touch к тому же ИЗБЫТОЧНЫ — коридор куска уже
помечен одним вызовом в pop_loose_mob_tick: 81 000 тактов в кадре впустую.
Итог по пиковому кадру: блиты 488 100 (34%), из них «железный» минимум
пикселей ~150 000; остальные ~1 150 000 (80% кадра) — наши накладные.
Узкое место не передача пикселей, а 16-битная арифметика в IX-кадрах.
Ответ на вопрос про uint8_t: просканированы все 109 .atl и наборы
TITLE/PV — максимум по игровому кадру 56x63 (kid3), фон 48x63, спрайты
комнаты принцессы 49x60. Шире 255 только восемь полноэкранных подложек
титров/сюжета (три 320x200 и пять 256..272), и все рисуются раз на экран.
Значит горячий путь переводится на байтовые габариты целиком, а подложкам —
отдельный банк / прямой libbgi (решение пользователя).
Документы (решение пользователя — вести работу по фазам, чтобы результаты
не теряись между сессиями):
docs/perf_l13_room23.md сцена, рецепт воспроизведения, зонды, канал clog,
сводка по кадрам, габариты спрайтов
docs/perf_green_phase.md зелёная фаза: раскладка, позиции G1..G6, журнал
docs/perf_cyan_phase.md циан: раскладка, позиции C1..C7, журнал
Отдельно записан рецепт воспроизведения: сцена повторяется ТОЛЬКО
перезапуском программы (ESC → зонды → roomtest). Возврат в комнату не
годится — упавшая плита уходит в страницу уровня насовсем; рестарт уровня
не годится — гряда доваливается заочно через trob комнаты 17, пока телепорт
уносит Кида; запись отладчиком на бегущей машине затирается тем же trob.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -928,6 +928,29 @@ HP/минуты, номера «особых» комнат и уровней (
|
||||
|
||||
## OPT-BLIT — цена отрисовки: чистка кодогена (СЛЕДУЮЩАЯ СЕССИЯ)
|
||||
|
||||
> **2026-08-17: контрольный замер снят, задача разложена по фазам.**
|
||||
> Работа теперь ведётся в трёх документах, которые живут между сессиями —
|
||||
> туда же писать результаты каждой правки:
|
||||
>
|
||||
> - [`../docs/perf_l13_room23.md`](../docs/perf_l13_room23.md) — сцена
|
||||
> (каскад 6 плит, ур. 13 комната 23), рецепт воспроизведения, зонды, канал
|
||||
> `clog`, сводка по кадрам, разбор габаритов спрайтов;
|
||||
> - [`../docs/perf_green_phase.md`](../docs/perf_green_phase.md) — ЗЕЛЁНАЯ
|
||||
> фаза: пик **805 000** при бюджете 400 000; позиции G1..G6;
|
||||
> - [`../docs/perf_cyan_phase.md`](../docs/perf_cyan_phase.md) — ЦИАН фаза:
|
||||
> пик **632 000** при бюджете 400 000; позиции C1..C7.
|
||||
>
|
||||
> Порядок работ: **G1** (окно клипа для запечки, −250..400 тыс.) → **G2**
|
||||
> (расколоть `draw_tile` + лист для ряда −1) → **C1** (убрать избыточный
|
||||
> `pop_cd_touch` в `mob_render`, −81 тыс.) → **G3/C3** (`blit_b_clip` на
|
||||
> байтовые габариты) → **C4** (разобрать `pop_char_fore(KID)`: 1 722 → 150 978).
|
||||
>
|
||||
> Синяя секция (**142 830**) в бюджет укладывается — не трогаем.
|
||||
> Ответ на вопрос про `uint8_t`: горячий путь можно переводить целиком,
|
||||
> максимум по всем игровым атласам **56×63**; шире 255 только восемь
|
||||
> полноэкранных подложек титров/сюжета (320×200 и т. п.), и они рисуются раз
|
||||
> на экран — им отдельный банк / прямой libbgi.
|
||||
|
||||
Открыто 2026-08-13 по итогам разбора зелёного блока. Контекст и все замеры
|
||||
— в memory `blit_cost_model` и `sdcc_z80_stack_locals_hot_loop`, протокол
|
||||
разбора — в коммитах `f89b7dd` / `b27b313` / этом.
|
||||
@@ -994,7 +1017,9 @@ grep -n "pop.*\n.*pop.*\n.*push" ... # чтение спилла
|
||||
- Пакетная пометка `pop_cd_touch` (`pop_cd_batch_begin/end`, скобка в
|
||||
`draw_tile`) — сделана, но выигрыш замером НЕ подтверждён: в захваченных
|
||||
кадрах скобка не срабатывала (блиты шли из холодной отрисовки комнаты).
|
||||
Переснять на кадрах ЗАПЕКАНИЯ.
|
||||
Переснять на кадрах ЗАПЕКАНИЯ. **2026-08-17: цена НЕпакетного вызова
|
||||
замерена — 4 502 такта, 28 % всей цены блита; в `mob_render` он к тому же
|
||||
избыточен (см. C1).**
|
||||
- Снять временную оснастку: `pop_dbg_m9..m16`, `pop_dbg_b1..b6`,
|
||||
`pop_dbg_wh`, `pop_dbg_kind`, `pop_dbg_rdmax*`, `mame/v306/run_bridge_log.sh`.
|
||||
- Цель по кадру не достигнута: зелёный пик был 792 012 при цели 400 000.
|
||||
|
||||
Reference in New Issue
Block a user