Луч видимости стража: колонка из таблицы вместо деления (Кид у шва)
tile_at_kid (guards.c) считала колонку честным / и %, хотя резидентная POP_TILE_DIV — это и есть tile_div_tbl оригинала, и остальной порт давно на неё переведён. У SDCC z80 пара / и % над int это __divsint плюс __modsint, который внутри снова зовёт __divsint — ~5 400 тактов на вызов. Зовут её в ЦИКЛЕ по колонкам между стражем и Кидом (check_can_guard_see_kid, seg003:761). Когда Кид у шва, его curr_col = −1, луч тянется через всю комнату: замер дал ВОСЕМЬ пар делений за кадр, около 43 000 тактов = 10 % растрового кадра, в фазе логики. После фикса таких вызовов не остаётся. Как ловилось: брейкпоинт на __divsint с печатью адреса возврата дал ret=C033 восемь раз за кадр; остановка на нём с dasm при замапленном банке показала HL−65 / ld de,#14 / call __divsint по смещению 0x24 банка 1. Снята и ложная тревога из прошлого коммита: пролог pop_char_fore на шве НЕ разбухает до 134 730 — это была ошибка зонда (адрес fore_tile в банке совпадает с кодом других банков, в интервал попадали чужие срабатывания). Чистый замер: пролог 16 950, как и в середине комнаты. Урок записан в «Как мерить» в docs/perf_backlog.md. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -24,7 +24,16 @@ MAME (`z80_profiling_method`) на роомтесте, уровень 1 комн
|
||||
только по ОДНОЙ функции с одинаковыми входами, а не по общей работе за
|
||||
кадр.
|
||||
- Кто делит: брейкпоинт на `__divsint`/`__divuint`/`__divuchar` с печатью
|
||||
адреса возврата — `bpset <addr>,1,{printf "ret=%04X\n",w@(sp); g}`.
|
||||
адреса возврата — `bpset <addr>,1,{printf "ret=%04X\n",w@(sp); g}`. Если
|
||||
адрес возврата в банке (>= 0xC000), поставить тот же брейкпоинт с условием
|
||||
`w@(sp)==<адрес>` и БЕЗ `g`: машина встанет с нужным банком в окне, и
|
||||
`dasm` покажет вызывающего.
|
||||
- **Брейкпоинт по адресу в банке ловит ВСЕ банки.** 0xC000..0xFFFF — общее
|
||||
окно, и один и тот же адрес есть у семи модулей сразу. Либо ловить через
|
||||
трамплин (`hl==<адрес>&&(de&0xff)==<банк>`), либо перепроверять, что
|
||||
срабатывания идут из нужной фазы: иначе в интервал попадает чужой код и
|
||||
цифры врут (так я намерил несуществующие 134 730 тактов в прологе
|
||||
`pop_char_fore`).
|
||||
- Трасса вызовов графики с параметрами: скрипт в истории сессии, ставит
|
||||
маркеры фаз на трамплин `___sdcc_bcall_ehl` (условие `hl==<адрес>&&(de&0xff)==<банк>`)
|
||||
и брейкпоинты на листья libbgi с печатью аргументов
|
||||
@@ -97,6 +106,34 @@ MAME (`z80_profiling_method`) на роомтесте, уровень 1 комн
|
||||
|
||||
---
|
||||
|
||||
## СДЕЛАНО 2026-08-10: деление в луче видимости стража (Кид у шва)
|
||||
|
||||
`tile_at_kid` (`guards.c`) считала колонку честным `/` и `%`, тогда как везде
|
||||
уже стоит резидентная таблица `POP_TILE_DIV` (это и есть `tile_div_tbl`
|
||||
оригинала). У SDCC z80 это `__divsint` плюс `__modsint`, а тот внутри снова
|
||||
зовёт `__divsint` — ~5 400 тактов на вызов.
|
||||
|
||||
Зовут её В ЦИКЛЕ по колонкам между стражем и Кидом
|
||||
(`check_can_guard_see_kid`, seg003:761). Когда Кид стоит У ШВА, его
|
||||
`curr_col = −1`, луч тянется через всю комнату, и за кадр набегало ВОСЕМЬ пар
|
||||
делений — около 43 000 тактов, 10 % растрового кадра, в фазе ЛОГИКИ.
|
||||
|
||||
Замер: брейкпоинт на `__divsint` с печатью адреса возврата дал `ret=C033`
|
||||
восемь раз за кадр; остановка на нём и дизассемблирование с правильным банком
|
||||
показали `HL−65`, `ld de,#14`, `call __divsint` по смещению 0x24 банка 1 —
|
||||
`tile_at_kid`. После фикса пар `C033` не остаётся ни одной.
|
||||
|
||||
**Заодно снята ложная тревога.** В прошлом замере я записал, что на шве
|
||||
пролог `pop_char_fore` разбухает до 134 730 тактов. Это была ошибка зонда:
|
||||
брейкпоинт на `fore_tile` стоял по адресу, который совпадает с кодом ДРУГИХ
|
||||
банков, и в интервал попадали чужие срабатывания. Чистый замер (Кид в
|
||||
колонке 0, спрайт свисает за левый край, окно `x −8..5`): пролог **16 950** —
|
||||
ровно как в середине комнаты, весь fore-проход 41 803, `pop_room_clip_borders`
|
||||
14 364. Урок в «Как мерить» выше: адрес в банке нужно либо проверять на
|
||||
уникальность, либо ловить через трамплин с условием на банк.
|
||||
|
||||
---
|
||||
|
||||
## 0. Дворцовая кладка в fore-проходе — **СДЕЛАНО 2026-08-10**
|
||||
|
||||
Все три шага выполнены; замер после — в конце пункта. Ниже сохранён исходный
|
||||
|
||||
Reference in New Issue
Block a user