From 5a42b2d24533c768ea824b0556fc97dfd16fd38f Mon Sep 17 00:00:00 2001 From: Alexander Petrov Date: Wed, 19 Aug 2026 18:17:38 +0300 Subject: [PATCH] =?UTF-8?q?P6a:=20=D1=83=D0=BA=D0=B0=D0=B7=D0=B0=D1=82?= =?UTF-8?q?=D0=B5=D0=BB=D1=8C=20=D0=BC=D0=BE=D0=B4=D0=B8=D1=84=D0=B8=D0=BA?= =?UTF-8?q?=D0=B0=D1=82=D0=BE=D1=80=D0=BE=D0=B2=20=D0=BA=D0=BE=D0=BC=D0=BD?= =?UTF-8?q?=D0=B0=D1=82=D1=8B=20=D0=BA=D1=8D=D1=88=D0=B8=D1=80=D1=83=D0=B5?= =?UTF-8?q?=D1=82=D1=81=D1=8F=20=D0=BC=D0=B5=D0=B6=D0=B4=D1=83=20trob'?= =?UTF-8?q?=D0=B0=D0=BC=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- applications/PoP/roomtest/pop_trob.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/applications/PoP/roomtest/pop_trob.c b/applications/PoP/roomtest/pop_trob.c index 6f9e9a0..53627c1 100644 --- a/applications/PoP/roomtest/pop_trob.c +++ b/applications/PoP/roomtest/pop_trob.c @@ -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++)