Реестр: сводка и статусы обновлены; замер тяжёлой позиции
Пользователь передвинул Кида на один осторожный шаг вправо (x = 106 вместо 99, колонка та же) — его спрайт начал пересекаться с тайлом (0,3), где одновременно чомпер и пламя факела. фаза лёгкая тяжёлая синяя 259 500 257 520 зелёная 181 068 180 870 циан 187 761 319 842 (+132 081) работа 628 542 758 358 Период кадра: 4 растра в 335 кадрах, 5 растров в 123 (27 %). Это уже не «стабильно медленно», а рывки. Куда ушли 132 тысячи: pop_char_draw(KID) 204 -> 54 738 и fore-проход Кида 4 356 -> 93 486. То есть Кид из «пропущен» превращается в полноценного персонажа за ~144 000 — столько же, сколько страж. Отсюда новая позиция P14: fore-проход персонажа, 62 778 у стража и ~89 000 у Кида, вместе около 152 000 = 20 % работы кадра. Это самая дорогая единичная статья. У Кида он дороже потому, что в его футпринте лежит чомпер со своим передним слоем. P3 переведён в «частично сбылось»: выигрыш держится только пока персонаж не подошёл к анимированному тайлу, а в игре он подходит постоянно. Итог семи закрытых позиций: 801 768 -> 628 542, то есть -22 %. До цели 430 000 остаётся снять 199 000 в лёгкой позиции и 328 000 в тяжёлой, а всё оставшееся в реестре даёт порядка 100 000. Арифметика не сходится — в реестр записаны три возможных решения (P13, осознанное расхождение с оригиналом, принять 4 растра), выбор за пользователем. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -179,6 +179,44 @@ if ((curr_modifier & 0x7F) < 6) {
|
|||||||
скорее всего перераскладка кода банка 3 компилятором; проверять отдельно
|
скорее всего перераскладка кода банка 3 компилятором; проверять отдельно
|
||||||
не стали, знак верный.
|
не стали, знак верный.
|
||||||
|
|
||||||
|
## 7. ТЯЖЁЛАЯ позиция: Кид на шаг правее [замер 2026-08-19]
|
||||||
|
|
||||||
|
Поставлена пользователем: один осторожный шаг вправо (x = 106 вместо 99,
|
||||||
|
колонка та же). Спрайт Кида начинает пересекаться с тайлом (0,3), где
|
||||||
|
одновременно чомпер и пламя факела — и `skip_mask` перестаёт его
|
||||||
|
пропускать.
|
||||||
|
|
||||||
|
| фаза | лёгкая | **тяжёлая** | разница |
|
||||||
|
|---|---:|---:|---:|
|
||||||
|
| синяя | 259 500 | 257 520 | −1 980 |
|
||||||
|
| зелёная (медиана) | 181 068 | 180 870 | −198 |
|
||||||
|
| **циан** | 187 761 | **319 842** | **+132 081** |
|
||||||
|
| **работа (медиана)** | 628 542 | **758 358** | **+129 816** |
|
||||||
|
| работа (максимум) | 744 384 | **876 612** | |
|
||||||
|
|
||||||
|
**Период кадра: 4 растра в 335 кадрах, 5 растров в 123 (27 %).** Это уже
|
||||||
|
не «стабильно медленно», а рывки: каждый четвёртый кадр длиннее соседних.
|
||||||
|
|
||||||
|
Разбор циана показывает, куда ушли 132 тысячи:
|
||||||
|
|
||||||
|
| участок | лёгкая | тяжёлая |
|
||||||
|
|---|---:|---:|
|
||||||
|
| `check_mirror` | 3 198 | 3 198 |
|
||||||
|
| `mob_draw` + `guard_over_kid` + `skip_mask` | 34 374 | 18 672 |
|
||||||
|
| **`pop_char_draw(KID)`** | **204** | **54 738** |
|
||||||
|
| соперник: `char_draw` + `char_fore` | 145 896 | 149 748 |
|
||||||
|
| **`fore_needed` + `char_fore(KID)` + борта** | **4 356** | **93 486** |
|
||||||
|
|
||||||
|
То есть Кид из «пропущен за 204 такта» превращается в полноценного
|
||||||
|
персонажа за ~144 000 — ровно столько же, сколько стоит страж.
|
||||||
|
|
||||||
|
**Главный вывод замера: самая дорогая единичная статья кадра — это
|
||||||
|
fore-проход персонажа.** 62 778 у стража и ~89 000 у Кида, вместе около
|
||||||
|
**152 000, то есть 20 % работы кадра**. У Кида он дороже потому, что в его
|
||||||
|
футпринте лежит чомпер, а у чомпера есть собственный передний слой
|
||||||
|
(`POP_CHOMP_FRAM_FOR`), который перерисовывается поверх персонажа каждый
|
||||||
|
кадр.
|
||||||
|
|
||||||
**Полная очередь оптимизаций с оценками — [`perf_registry.md`](perf_registry.md).**
|
**Полная очередь оптимизаций с оценками — [`perf_registry.md`](perf_registry.md).**
|
||||||
Там же разложена цена одного блита фона по этапам (замер 2026-08-19, 1603
|
Там же разложена цена одного блита фона по этапам (замер 2026-08-19, 1603
|
||||||
блита) и модель зелёной фазы этой сцены.
|
блита) и модель зелёной фазы этой сцены.
|
||||||
|
|||||||
@@ -150,7 +150,39 @@
|
|||||||
|
|
||||||
Новое, найдено 2026-08-19.
|
Новое, найдено 2026-08-19.
|
||||||
|
|
||||||
### P3. Персонажи будятся каждый кадр [модель: −70 000, следствие P1]
|
### P14. Fore-проход персонажа — 62 778…89 000 НА ПЕРСОНАЖА [замер 2026-08-19]
|
||||||
|
|
||||||
|
**Самая дорогая единичная статья кадра: около 152 000 на двоих, 20 % работы.**
|
||||||
|
|
||||||
|
`pop_char_fore` = два трамплина в банк 2 (`pop_fore_set_clip` +
|
||||||
|
`pop_fore_over_char`) плюс обход тайлов футпринта, в каждом `fore_tile`.
|
||||||
|
У Кида дороже, чем у стража, потому что в его футпринте лежит чомпер, а у
|
||||||
|
чомпера есть собственный передний слой (`POP_CHOMP_FRAM_FOR`), который
|
||||||
|
перерисовывается поверх персонажа каждый кадр.
|
||||||
|
|
||||||
|
Что можно пробовать, по возрастанию радикальности:
|
||||||
|
|
||||||
|
1. слить два трамплина в один вызов (мелочь, ~4 000);
|
||||||
|
2. **P10** — брать футпринт из физики, а не считать заново (−11 574 на
|
||||||
|
проход, то есть до −23 000 на двоих);
|
||||||
|
3. гейт по сигнатуре: пропускать проход, если не изменились ни кадр
|
||||||
|
персонажа, ни тайлы его футпринта. **Это расхождение с оригиналом** —
|
||||||
|
он рисует foretable безусловно;
|
||||||
|
4. **P13** — objtable и отложенные таблицы: у оригинала «посетить тайл»
|
||||||
|
стоит копейки именно потому, что таблицы только копят записи.
|
||||||
|
|
||||||
|
### P3. Персонажи будятся каждый кадр ✅ ЧАСТИЧНО СБЫЛОСЬ
|
||||||
|
|
||||||
|
**В лёгкой позиции — да:** после P1 `pop_char_draw(KID)` стоит 204 такта,
|
||||||
|
метка от чомпера до Кида больше не дотягивается.
|
||||||
|
|
||||||
|
**В тяжёлой позиции — нет:** стоит Киду шагнуть на 7 пикселей вправо, и его
|
||||||
|
спрайт пересекается с тайлом чомпера и пламени, `skip_mask` перестаёт
|
||||||
|
пропускать, и он снова стоит ~144 000 (54 738 draw + ~89 000 fore). То
|
||||||
|
есть выигрыш P3 держится только пока персонаж не подошёл к анимированному
|
||||||
|
тайлу — а в игре он к нему подходит постоянно.
|
||||||
|
|
||||||
|
Исходная оценка (−70 000) была:
|
||||||
|
|
||||||
heal 141 048 + отрисовка 148 566 = 290 000 тактов (36 % работы) уходят на то,
|
heal 141 048 + отрисовка 148 566 = 290 000 тактов (36 % работы) уходят на то,
|
||||||
что `pop_char_skip_mask` не может пропустить ни Кида, ни стража: фон трогают
|
что `pop_char_skip_mask` не может пропустить ни Кида, ни стража: фон трогают
|
||||||
@@ -294,67 +326,71 @@ BUG-LATTICE-DOORTOP, BUG-SEAM-WEDGE-1) — только отдельным за
|
|||||||
## 4. ПЛАН РАБОТ — состояние между сессиями
|
## 4. ПЛАН РАБОТ — состояние между сессиями
|
||||||
|
|
||||||
Рабочий чеклист. Правило: одна позиция = один заход = один коммит с замером
|
Рабочий чеклист. Правило: одна позиция = один заход = один коммит с замером
|
||||||
до/после на сцене 11/15. Замер обязателен даже когда «очевидно» — из шести
|
до/после на сцене 11/15. Замер обязателен даже когда «очевидно» — из семи
|
||||||
сделанных позиций две дали не то, что ожидалось.
|
закрытых позиций ТРИ дали не то, что ожидалось (P1 — вдвое меньше, P2a —
|
||||||
|
почти ничего, таблицы порогов — регресс).
|
||||||
|
|
||||||
| # | что | статус | факт |
|
### Закрыто
|
||||||
|---|---|---|---|
|
|
||||||
| P5 | `loose_tick`: гейты холостого хода | ✅ **сделано** 2026-08-19 | −33 840 на кадре (ждали −28 000) |
|
|
||||||
| P2 | замер синей фазы | ✅ замерено 2026-08-19 | гипотеза «трамплины» отвергнута |
|
|
||||||
| P6 | замер `process_trobs` | ✅ замерено 2026-08-19 | 11 058 префетч + ~43 000 цикл |
|
|
||||||
| P1 | чомпер: перерисовка только при фазе < 6 | ✅ **сделано** 2026-08-19 | −110 802 (ждали −160 000) |
|
|
||||||
| P2a | `coll_scan` в 8 бит + снят с IX | ✅ **сделано** 2026-08-19 | −3 486 в коллизиях, −2 892 на кадре |
|
|
||||||
| P2b | луч видимости: колонки + один банковый вызов | ✅ **сделано** 2026-08-19 | −26 448 (ждали −30 000) |
|
|
||||||
| P4 | накладные блита (4 правки) | ⬜ **следующее** | ждём −28 000 |
|
|
||||||
| P11 | мелочи с известной ценой | ⬜ | ждём −26 000 |
|
|
||||||
| P10 | футпринт персонажа из физики | ⬜ | ждём −23 000 |
|
|
||||||
| P6a/P6b | `trob_modif` из цикла, кэш префетча | ⬜ | ждём −20 000 |
|
|
||||||
| P7 | раскол `draw_tile` (G5) | ⬜ | для 13/23, не для 11/15 |
|
|
||||||
| P8/P9 | HEAL-WIDTH + G8 | ⬜ обязательная | для сцен с плитами |
|
|
||||||
| P12 | снять оснастку | ⬜ ПОСЛЕДНЕЙ | без неё не мерить |
|
|
||||||
|
|
||||||
### Достижим ли период 3 растра — арифметика после замеров
|
| # | что | факт |
|
||||||
|
|---|---|---|
|
||||||
|
| P5 | `loose_tick`: гейты холостого хода | **−33 840** (ждали −28 000) |
|
||||||
|
| P1 | чомпер: перерисовка только при фазе < 6 | **−110 802** (ждали −160 000) |
|
||||||
|
| P2b | луч видимости: колонки + один банковый вызов | **−26 448** (ждали −30 000) |
|
||||||
|
| P2a | `coll_scan` в 8 бит + снят с IX | **−2 892** (крупной статьи в физике нет) |
|
||||||
|
| P3 | Кид перестал будиться каждый кадр | сбылось само после P1 — но только в ЛЁГКОЙ позиции |
|
||||||
|
| P2/P6 | замеры синей фазы и `process_trobs` | гипотеза «трамплины на спецсобытиях» отвергнута |
|
||||||
|
| — | замер цианной фазы | крупного лишнего в отрисовке персонажа нет |
|
||||||
|
|
||||||
Работа сейчас **767 928**, цель **430 000**, снять надо **338 000**. Что
|
### Осталось, по убыванию ожидаемого эффекта
|
||||||
известно и посчитано:
|
|
||||||
|
|
||||||
| источник | ожидание |
|
| # | что | ожидание | риск | комментарий |
|
||||||
|---|---:|
|
|---|---|---:|---|---|
|
||||||
| ~~P1 (чомпер)~~ | ~~−160 000~~ → **сделано, −110 802** |
|
| **P14** | **fore-проход персонажа** — 62 778 у стража, ~89 000 у Кида | **до −80 000** | высокий | НОВОЕ, самая дорогая статья кадра (20 %). Включает P10 как первый шаг |
|
||||||
| P3 (Кид перестанет будиться) | −70 000 — **под вопросом**, см. ниже |
|
| P4 | накладные блита (4 правки) | −28 000 | низкий | 6 126 фиксированных на любой блит |
|
||||||
| P2b (гейт луча видимости) | −30 000 |
|
| P11 | мелочи с известной ценой | −26 000 | низкий | `clip_char_top` 8 658 подтверждён замером |
|
||||||
| P4 (накладные блита) | −28 000 |
|
| P10 | футпринт персонажа из физики | −23 000 | средний | часть P14 |
|
||||||
| P11 (мелочи) | −26 000 |
|
| P6a/P6b | `trob_modif` из цикла, кэш префетча | −20 000 | низкий | тот же паттерн трамплина в цикле |
|
||||||
| P10 (футпринт из физики) | −23 000 |
|
| P7 | раскол `draw_tile` (G5) | −50 000 в 13/23 | средний | в 11/15 не играет |
|
||||||
| P6a+P6b | −20 000 |
|
| P8/P9 | HEAL-WIDTH + G8 | 5-6 % цены heal'ов | низкий/средний | **обязательная** по решению пользователя; для сцен с плитами |
|
||||||
| **сумма оставшегося** | **−197 000** |
|
| P13 | objtable + отложенные таблицы, единый проход по тайлам | не оценено | очень высокий | большой рефакторинг слоя фона |
|
||||||
|
| P12 | снять оснастку | −6 000 | нулевой | **последней**: без неё не мерить |
|
||||||
|
|
||||||
**После P1 картина изменилась к худшему.** Снять с дорогого кадра надо
|
### Текущее состояние бюджета
|
||||||
336 000, а всё оставшееся в списке даёт 197 000 — и это при оптимистичных
|
|
||||||
оценках. Вдобавок P3 (Кид перестанет будиться) теперь под вопросом: циан
|
|
||||||
после P1 не сдвинулся ни на такт (187 761), то есть метки от чомпера и
|
|
||||||
факелов продолжают будить обоих персонажей в каждом кадре.
|
|
||||||
|
|
||||||
Значит без **P2a — разбора `pop_phys_tick`** (105 246 тактов на физику двух
|
|
||||||
НЕПОДВИЖНЫХ персонажей, цена измерена, причина не найдена) период 3 растра
|
|
||||||
не берётся. Это и есть следующая крупная позиция.
|
|
||||||
|
|
||||||
**Текущее состояние бюджета 11/15:**
|
|
||||||
|
|
||||||
| | работа | синяя | зелёная | циан | период |
|
| | работа | синяя | зелёная | циан | период |
|
||||||
|---|---:|---:|---:|---:|---:|
|
|---|---:|---:|---:|---:|---:|
|
||||||
| до оптимизации | 801 768 | 293 238 | 320 916 | 187 758 | 4 растра |
|
| до оптимизации | 801 768 | 293 238 | 320 916 | 187 758 | 4 растра |
|
||||||
| после P5 | 767 928 | 285 864 | 294 384 | 187 764 | 4 растра |
|
| после P5 | 767 928 | 285 864 | 294 384 | 187 764 | 4 |
|
||||||
| после P1 (медиана) | **657 882** | 286 503 | 183 420 | 187 761 | 4 растра |
|
| после P1 (медиана) | 657 882 | 286 503 | 183 420 | 187 761 | 4 |
|
||||||
| после P1 (дорогой кадр, 40 %) | 765 936 | 286 503 | 291 888 | 187 761 | 4 растра |
|
| после P2a | 654 990 | 283 215 | 183 798 | 187 812 | 4 |
|
||||||
| после P2a (медиана) | 654 990 | 283 215 | 183 798 | 187 812 | 4 растра |
|
| **после P2b (лёгкая позиция)** | **628 542** | 259 500 | 181 068 | 187 761 | 4 |
|
||||||
| после P2b (медиана) | **628 542** | 259 500 | 181 068 | 187 761 | 4 растра |
|
| **ТЯЖЁЛАЯ позиция (Кид на шаг правее)** | **758 358** | 257 520 | 180 870 | **319 842** | **4 и 5** |
|
||||||
|
|
||||||
Цель — уложить РАБОТУ в 430 000 (тогда период станет 3 растра вместо 4;
|
Итог семи позиций: **801 768 → 628 542, то есть −22 %**.
|
||||||
хвост кадра — три `gfx_wait_vsync`). Осталось снять **228 000** с медианы
|
|
||||||
и **336 000** с дорогого кадра. Считать надо по ДОРОГОМУ: период задаётся
|
### Достижима ли цель — арифметика на 2026-08-19
|
||||||
каждым кадром отдельно, и пока дорогие кадры не влезут, 40 % кадров будут
|
|
||||||
идти по 4 растра.
|
Цель: работа ≤ 430 000, тогда период станет 3 растра (хвост кадра — три
|
||||||
|
`gfx_wait_vsync`).
|
||||||
|
|
||||||
|
- в ЛЁГКОЙ позиции снять надо **199 000**;
|
||||||
|
- в ТЯЖЁЛОЙ — **328 000**, и там уже 27 % кадров идут по 5 растров.
|
||||||
|
|
||||||
|
Всё оставшееся в списке, кроме P13, даёт по оценкам **порядка 100 000** — и
|
||||||
|
это оптимистично. **Арифметика не сходится:** сцена с двумя персонажами,
|
||||||
|
чомпером и двумя факелами в три растра не укладывается без одного из трёх
|
||||||
|
решений:
|
||||||
|
|
||||||
|
1. **P13** — переход на objtable и отложенные таблицы, как в оригинале
|
||||||
|
(единственный резерв нужного размера, но это переписывание слоя фона);
|
||||||
|
2. **осознанное расхождение с оригиналом** — например, не перерисовывать
|
||||||
|
передний слой персонажа, пока не изменились ни персонаж, ни тайлы под
|
||||||
|
ним (гейт по сигнатуре футпринта);
|
||||||
|
3. **принять 4 растра** как рабочий режим для сцен такой плотности и
|
||||||
|
выравнивать период, чтобы не было рывков 4/5.
|
||||||
|
|
||||||
|
Решение за пользователем — это выбор между точностью порта и скоростью.
|
||||||
|
|
||||||
### Как воспроизвести сцену (важно для следующей сессии)
|
### Как воспроизвести сцену (важно для следующей сессии)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user