P6a: указатель модификаторов комнаты кэшируется между trob'ами

pop_trob_modif объявлен __banked, а звался он на КАЖДЫЙ trob внутри
цикла pop_process_trobs — при том что комната у них в подавляющем
большинстве кадров одна (чужие появляются только у брошенных плит
соседней комнаты).  Тот же паттерн «трамплин в цикле», что дал -23 784 на
луче видимости (P2b) и -14 118 на guard_over_kid (P16).

Замер 11/15: цикл trobs 78 726 -> 74 964, работа кадра 438 324 -> 437 484.

ОЖИДАНИЕ НЕ ОПРАВДАЛОСЬ: в реестре стояло -20 000 на пару P6a/P6b, а
вышло -840.  Причина простая — trob'ов в комнате всего несколько, и кэш
экономит два-три вызова, а не двадцать.  Оценка была построена на
аналогии с лучом видимости, где вызовов было девять на КАЖДЫЙ кадр.

Проверено в MAME на чистом запуске: факелы, чомпер и страж рисуются
правильно, хост-тесты зелёные.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-19 18:17:38 +03:00
parent 52a36caa75
commit 5a42b2d245
+20 -1
View File
@@ -635,13 +635,31 @@ void pop_process_trobs(uint8_t cur_room) __banked
pop_dbg_m8(); /* ЗАМЕР: префетч кодов тайлов сделан */
/* Указатель на модификаторы КОМНАТЫ кэшируется между итерациями.
*
* pop_trob_modif объявлен __banked, и вызов его на КАЖДЫЙ trob — это
* трамплин из банка 6 в банк 6 же... нет: из горячего цикла в банковую
* функцию, то есть полный переход через резидент. А комната у trob'ов
* в подавляющем большинстве кадров ОДНА (все они из cur_room, чужие
* появляются лишь у брошенных плит соседней комнаты). Тот же паттерн
* «трамплин в цикле», что дал −23 784 на луче видимости стража
* (P2b) и 14 118 на guard_over_kid (P16).
*
* Сбрасывается на каждом кадре: room_seen внутри pop_trob_modif живёт
* дольше, но указатель на строку room_modif может смениться при
* перезагрузке комнаты, поэтому кэш локальный для одного прохода. */
{
uint8_t mod_room = 0; /* 0 = «ещё не брали» (комнаты 1..24) */
uint8_t *mod = 0;
for (i = 0; i < trobs_count; i++) {
uint8_t room = trobs[i].room;
uint8_t tp = trobs[i].tilepos;
uint8_t code = trob_code[i];
uint8_t *mod = pop_trob_modif(room);
int8_t type = trobs[i].type;
if (room != mod_room) { mod = pop_trob_modif(room); mod_room = room; }
switch (code) {
case TILE_SPIKE:
animate_spike(&mod[tp], &type);
@@ -819,6 +837,7 @@ void pop_process_trobs(uint8_t cur_room) __banked
}
}
}
} /* конец блока с кэшем mod/mod_room */
/* compact: удалить завершённые (type < 0). */
for (i = 0; i < trobs_count; i++)