Инвентаризация делений по .asm: убраны три, остальные разобраны
Обход всех сгенерированных .asm (awk по `call __div/__mod/__mul` с привязкой к строке исходника) нашёл 31 вызов в 9 модулях. Три из них были в горячем пути: - pop_cdraw.c calc_screen_x_coord: `x * 8 / 7` -> __divsint, 2 400 тактов на ПЕРСОНАЖА КАЖДЫЙ КАДР (два вызова при живом сопернике). Заменено тождеством 8x/7 == x + x/7 плюс таблица DIV7[256] в банке 4 — резидент не тронут, обычный диапазон (obj_x 0..252 при x_bump 58..184) покрыт целиком, деление осталось только хвостом для шва (render_dx = ∓140). - pop_guard.c guard_col_from_x: /14 и %14 звались БЕЗУСЛОВНО, мимо POP_TILE_DIV — единственное 16-битное деление без подключённой таблицы. - pop_trob.c animate_chomper: `tp / 10` на чомпера каждый кадр, при том что TP_ROW/TP_COL лежали в этом же файле, но ниже по тексту. Таблицы подняты выше чомперов. Остальные 25 оставлены осознанно и расписаны в TASKS_OPEN.md: хвосты за таблицей (x вне 0..255 = персонаж в соседней комнате), намеренный медленный хвост pop_y_to_row, недостижимая ветка pop_rnd_fit и холодные места (вход стража, старт уровня, читы, имя файла, отладочный HUD). В банках 4, 6, 7 теперь ноль __div*. Тождество 8x/7 закреплено тестом geom_mul8div7_identity (перебор −420..700), таблица DIV7 сверена с x//7. tests-host: [geom] 840 -> 1961, все 5 наборов прошли. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -435,6 +435,54 @@ wait-state'ы, и замеренная стоимость выходит **≈ 2
|
||||
(перебор −400..400 против исходной формулы) — вызовы разбросаны по трём
|
||||
банкам, и соблазн написать деление «по месту» возвращается.
|
||||
|
||||
### Полная инвентаризация делений 2026-08-10
|
||||
|
||||
Способ (повторяемый одной командой из `.sprinter-cc-roomtest/`):
|
||||
|
||||
```
|
||||
awk '/^;[a-z_0-9]+\.[ch]:[0-9]+:/{s=$0} /^\tcall\t__(div|mod|mul)/{printf "%-22s %-12s %s\n",FILENAME,$2,s}' *.asm
|
||||
```
|
||||
|
||||
Найден **31 вызов в 9 модулях**. Прибрано три места, остальное разобрано и
|
||||
осознанно оставлено.
|
||||
|
||||
Убрано:
|
||||
|
||||
| место | что было | почему стоило |
|
||||
|---|---|---|
|
||||
| `pop_cdraw.c` `calc_screen_x_coord` (2 вызова) | `x * 8 / 7` = `__divsint`, **2 400 тактов НА ПЕРСОНАЖА КАЖДЫЙ КАДР** | последнее деление в горячем пути; ~4 800/кадр при живом сопернике |
|
||||
| `pop_guard.c` `guard_col_from_x` | `/14` + `%14` **безусловно**, мимо `POP_TILE_DIV` | единственное 16-битное деление, у которого таблица вообще не была подключена |
|
||||
| `pop_trob.c` `animate_chomper` | `tp / 10` = `__divuchar` на чомпера каждый кадр | таблицы `TP_ROW`/`TP_COL` уже лежали в ЭТОМ ЖЕ файле, но ниже по тексту — чомперы их не видели |
|
||||
|
||||
Приём для `×8/7`: тождество **`8x/7 == x + x/7`** (7x делится нацело, поэтому
|
||||
усечение обеих частей совпадает — и для отрицательных с трункейтом к нулю
|
||||
тоже). Дальше `x/7` — таблица `DIV7[256]` в банке 4 (резидент не тронут).
|
||||
Диапазон покрыт не «частый», а весь обычный: `x_bump[5..14] = 58..184`, то
|
||||
есть `obj_x = 2*fwd − 116` у персонажа в отрисованной комнате лежит в 0..252;
|
||||
хвост нужен только на шве (`render_dx = ∓140`). Тождество проверено тестом
|
||||
`geom_mul8div7_identity`, сама таблица — сверкой с `x//7` питоном.
|
||||
|
||||
Оставлено сознательно (НЕ трогать, это не забытые места):
|
||||
|
||||
- **Хвосты за таблицей** — `guards.c:84`, `pop_bg.c:497`, `roomtest.c:163`,
|
||||
`pop_map.c:412`: срабатывают только при x вне 0..255, то есть когда
|
||||
персонаж в соседней комнате. Убирать их — это расширять `POP_TILE_DIV` до
|
||||
−140..395 (+280 Б резидента) ради редкого пути.
|
||||
- **`pop_geom.c:21`** — намеренный медленный хвост `pop_y_to_row` (см. выше
|
||||
про подъём деления SDCC).
|
||||
- **`pop_geom.c:52`** — `v % n` в `pop_rnd_fit` для не-степени двойки:
|
||||
оригинал зовёт `prandom(1)/(255)/(0xFF)`, все три идут веткой с маской,
|
||||
сюда управление не приходит вовсе.
|
||||
- **Холодные, раз на комнату/уровень/событие**: `pop_guard.c:266/268/269`
|
||||
(вход стража), `pop_map.c:310` (пробуждение скелета), `pop_trob.c` дверь
|
||||
уровня, `roomtest.c:473/663/887` (читы и старт), `pop_level.c:131/132`
|
||||
(имя файла уровня), `roomtest.c:976/977` (отладочный HUD номера комнаты).
|
||||
Каждое — единицы вызовов за секунды игры; таблицы под них только раздули
|
||||
бы код.
|
||||
|
||||
Итог: **в горячем пути делений не осталось**. В банках 4, 6, 7 — ноль
|
||||
`__div*`; всё, что видно в списке выше, либо за быстрым путём, либо холодное.
|
||||
|
||||
**Профиль работы за логический кадр СЕЙЧАС (409 956 тактов + ~15 600 ввод):**
|
||||
|
||||
| блок | тактов | % растрового кадра |
|
||||
|
||||
Reference in New Issue
Block a user