Профиль дворца: циан = fore-проход, 27% кадра на ноль пикселей
Разбивка логического кадра брейкпоинтами (уровень 4, Кид неподвижно на (1,7)): работа 517 609 тактов = 120% растрового кадра, период 4 кадра. Циан (PROF(6)) — 233 515 = 54% растрового кадра, из них pop_char_fore(KID) = 171 693. Внутри fore-прохода шесть тайлов, и два из них — СТЕНА ряда 2 под ногами Кида — стоят 74 310 и 65 553. Дворцовая кладка на тайл: 6 wpp_fill (~3 100) + 5 pop_wall_b (~9 760) ≈ 60 000. Окно клипа в этот момент x 229..241, y 106..147 (прочитано из pop_t_fclip_*), верхний кусок узора стоит на y=157 — не пересекается вовсе, тайл (2,6) промахивается и по x. То есть 139 863 такта за кадр рисуют ноль пикселей; снятие уводит период с 4 растровых кадров на 3. Записано пунктом 0 в docs/perf_backlog.md с тремя вариантами лечения. Состав узора сверен с SDLPoP (seg008.c:1943) — порт дословный. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -44,6 +44,88 @@ MAME (`z80_profiling_method`) на роомтесте, уровень 1 комн
|
|||||||
Одна перерисовка персонажа = **~137 000 тактов = 32 % растрового кадра**,
|
Одна перерисовка персонажа = **~137 000 тактов = 32 % растрового кадра**,
|
||||||
из них полезной работы (heal 20×19 + спрайт 12×41) — меньше трети.
|
из них полезной работы (heal 20×19 + спрайт 12×41) — меньше трети.
|
||||||
|
|
||||||
|
## Профиль дворца (уровень 4) на 2026-08-10
|
||||||
|
|
||||||
|
Сцена: уровень 4, Кид НЕПОДВИЖНО стоит на (1,7) (комната с решёткой),
|
||||||
|
стража нет. Разбивка одного логического кадра брейкпоинтами на границах
|
||||||
|
фаз (адреса `PROF()` из `roomtest.lst` + базы `_CODE = 0x42AD`):
|
||||||
|
|
||||||
|
| фаза | тактов | доля работы |
|
||||||
|
|---|---:|---:|
|
||||||
|
| ввод + читы + heal | 59 340 | 11 % |
|
||||||
|
| логика (kid_tick, phys_tick, страж, боёвка) | 85 356 | 16 % |
|
||||||
|
| `pop_loose_tick` | 27 396 | 5 % |
|
||||||
|
| `pop_process_trobs` | 106 107 | 21 % |
|
||||||
|
| `pop_redraw_needed` | 447 | — |
|
||||||
|
| шов / смена уровня / вспышка | 5 448 | 1 % |
|
||||||
|
| `guard_over_kid` + `pop_char_skip_mask` | 4 788 | 1 % |
|
||||||
|
| `pop_char_draw(KID)` | 52 206 | 10 % |
|
||||||
|
| соперник + `loose_mob_draw_over` + `hp_draw` | 4 086 | 1 % |
|
||||||
|
| **`pop_char_fore(KID)`** | **171 693** | **33 %** |
|
||||||
|
| `pop_room_clip_borders` + прочее | 742 | — |
|
||||||
|
| **ИТОГО работа** | **517 609** | 120 % растрового кадра → период **4 кадра** |
|
||||||
|
|
||||||
|
По цветам бордюра: синий (`PROF(2)`) 144 696 (28 %), зелёный (`PROF(4)`)
|
||||||
|
139 398 (27 %), циан (`PROF(6)`) 233 515 (45 % работы = 54 % растрового
|
||||||
|
кадра, начинается на 74 % первого кадра и кончается на 123 %).
|
||||||
|
|
||||||
|
## 0. Дворцовая кладка в fore-проходе — 27 % кадра НА НОЛЬ ПИКСЕЛЕЙ
|
||||||
|
|
||||||
|
**Цена: 139 863 такта за кадр (32 % растрового кадра), полезных пикселей —
|
||||||
|
ровно ноль.** Самая дорогая известная позиция; снятие её одной уводит
|
||||||
|
работу с 517 609 до ~378 000, то есть период с **4 растровых кадров на 3**.
|
||||||
|
|
||||||
|
Замер (уровень 4, Кид на (1,7)). Окно fore-клипа в этот момент —
|
||||||
|
`x 229..241, y 106..147` (прочитано из `pop_t_fclip_*` брейкпоинтом).
|
||||||
|
`pop_fore_over_char` обходит 6 тайлов:
|
||||||
|
|
||||||
|
| тайл | тактов |
|
||||||
|
|---|---:|
|
||||||
|
| (0,6) (0,7) (1,6) (1,7) | 2 800 – 4 600 каждый |
|
||||||
|
| **(2,6) — стена** | **74 310** |
|
||||||
|
| **(2,7) — стена** | **65 553** |
|
||||||
|
|
||||||
|
Ряд 2 этой комнаты — стена, и он лежит ПОД ногами Кида, то есть попадает в
|
||||||
|
его fore-окно всегда. Внутри одного тайла стены `wall_pattern_palace`
|
||||||
|
делает 6 × `wpp_fill` (≈ 3 100 каждый) + 5 × `pop_wall_b` (≈ 9 760 каждый)
|
||||||
|
≈ 60 000 тактов.
|
||||||
|
|
||||||
|
Ни один кусок в окно не попадает:
|
||||||
|
- верхняя заливка стоит на `dmy - 59 = 157`, окно кончается на `y = 147`;
|
||||||
|
все остальные куски ещё ниже;
|
||||||
|
- тайл (2,6) занимает `x 192..223`, окно начинается с `x = 229` — он
|
||||||
|
промахивается и по горизонтали тоже.
|
||||||
|
|
||||||
|
Тайл всё равно проходит, потому что предфильтр в `fore_tile` (pop_bg.c,
|
||||||
|
`x0 < fclip_x1 && x0 + 40 > fclip_x0 && y0 - 8 < fclip_y1 && y0 + 70 >
|
||||||
|
fclip_y0`) намеренно грубый — габарит 40×78 на тайл. Дальше `wpp_fill`
|
||||||
|
честно режет по окну и выходит с пустым прямоугольником, но 3 100 тактов на
|
||||||
|
арифметику клипа уже потрачены, а `pop_wall_b` о существовании окна не знает
|
||||||
|
вовсе: он идёт в `atlas_image` + `gfx_w0_map`, читает `w`/`h` и только там
|
||||||
|
обнаруживает, что рисовать нечего.
|
||||||
|
|
||||||
|
Что делать (по возрастанию объёма):
|
||||||
|
1. **Ранний выход из `wall_pattern_palace`**: самый верхний пиксель узора —
|
||||||
|
`dmy - 59`, самый нижний — `dby + высота нижнего декаля`. Один
|
||||||
|
`if (pop_t_fclip_on && (fclip_y1 <= dmy - 59 || fclip_y0 > dby + h))
|
||||||
|
return;` плюс такая же проверка по `x` убивает оба тайла целиком почти
|
||||||
|
даром.
|
||||||
|
2. Прогнать `pop_wall_b` в этом узоре через ту же проверку окна, что уже
|
||||||
|
есть у `wpp_fill` (нужны размеры кусков — см. п. 2 ниже, «размеры из
|
||||||
|
каталога атласа»).
|
||||||
|
3. Сузить сам предфильтр `fore_tile` до реального габарита узора вместо
|
||||||
|
40×78 — тогда лечится не только дворец.
|
||||||
|
|
||||||
|
Порядок в подземелье тот же, но дешевле: `wall_pattern` в подземелье делает
|
||||||
|
до 3 блитов и ни одной заливки (~29 000 на тайл против ~60 000). Это же
|
||||||
|
объясняет, почему после перехода на дворцовый тайлсет период вырос.
|
||||||
|
|
||||||
|
Сверено с SDLPoP (`seg008.c:1943 wall_pattern`, ветка
|
||||||
|
`!is_dungeon && GRAPHICS_VGA`): состав узора у нас дословный — 5
|
||||||
|
`add_wipetable` + 4 декаля + нижняя заливка + нижний декаль. Расходимся не
|
||||||
|
составом, а тем, что оригинал складывает всё в `foretable` и рисует одним
|
||||||
|
`draw_table()`, у которого «посетить тайл» стоит копейки (см. п. 6).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 1. Футпринт персонажа — брать из физики, а не считать заново
|
## 1. Футпринт персонажа — брать из физики, а не считать заново
|
||||||
|
|||||||
Reference in New Issue
Block a user