Убраны три последних /63 %4 в pop_room.c — вызов pop_y_to_row

mob_tick_one (927) и mob_render (976/977) считали `(y+60)/63 % 4 - 1`
вручную, хотя pop_y_to_row — точный эквивалент этой формулы на всём
int16_t (включая усечение деления к нулю для отрицательных).  В asm это
были три пары __divsint+__modsint, ~16 200 тактов (3,8 % кадра) — только
пока кусок плиты в полёте, то есть в самом тяжёлом кадре.

В банке 7 теперь ноль __divsint.  Эквивалентность закреплена тестом
geom_y_to_row_matches_formula: перебор −400..400 против исходной формулы
(вызовы разбросаны по трём банкам, соблазн написать деление «по месту»
возвращается).  tests-host: [geom] 39 -> 840, все 5 наборов прошли.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-10 20:10:52 +03:00
parent ec3cca5e1e
commit 8cac51d592
3 changed files with 30 additions and 3 deletions
+10
View File
@@ -425,6 +425,16 @@ wait-state'ы, и замеренная стоимость выходит **≈ 2
`__divuchar` с печатью адреса возврата (`printf "%04X", w@(sp)`) — сразу
видно, кто и сколько раз делит за кадр.
**Хвост подобран 2026-08-10.** После переписи `pop_y_to_row` в pop_room.c
осталось ТРИ места, считавших `(y+60)/63 % 4 - 1` вручную (927 в
`mob_tick_one`, 976/977 в `mob_render`) — сгенерированный asm подтвердил
пару `__divsint`+`__modsint` в каждом. Это ~16 200 тактов (3,8 % кадра), но
только пока кусок плиты в полёте — то есть ровно в самом тяжёлом кадре.
Заменены вызовом `pop_y_to_row`; в банке 7 теперь НОЛЬ `__divsint`.
Эквивалентность закреплена тестом `geom_y_to_row_matches_formula`
(перебор −400..400 против исходной формулы) — вызовы разбросаны по трём
банкам, и соблазн написать деление «по месту» возвращается.
**Профиль работы за логический кадр СЕЙЧАС (409 956 тактов + ~15 600 ввод):**
| блок | тактов | % растрового кадра |