Ускорение холостого хода: указательный обход вместо arr[i] в горячих циклах
Замер зелёного блока (комната 23 уровня 13, MAME, такты эмулятора) показал, что 86% его стоимости в ПОКОЕ — это pop_loose_tick, который не делает ничего. Причина — кодоген SDCC, подтверждена чтением .asm. С `int pos` и записью pop_loose_modif[pos] компилятор держал счётчик в IX-фрейме, каждую итерацию заново складывал 16-битный адрес элемента, клал его в локал и тут же вычитывал обратно парами `pop bc / pop hl / push hl / push bc`. 40 холостых итераций (30 тайлов + 10 потолков) стоили 27 936 тактов. То же в pop_loose_mob_tick: запись mobs[i] заставляла умножать i на sizeof(mob_t)=15 заново под КАЖДОЕ поле (.active/.clean/.x/.y), 14 пустых слотов — 35 790. Правка — обход указателем, счётчик uint8_t, пустые слоты отсеиваются в вызывающем цикле (а не гардом внутри mob_tick_one, до которого надо ещё дойти). Холостая итерация стала `ld a,(de) / or a,a / jp Z` — три инструкции вместо дюжины с обращениями к памяти. Результат (такты MAME, холостой кадр): циклы по тайлам 27 936 -> 9 852 (2,8x) pop_loose_mob_tick 35 790 -> 7 416 (4,8x) pop_loose_tick 70 866 -> 24 384 (2,9x) ЗЕЛЁНЫЙ БЛОК 82 242 -> 35 760 (2,3x) Банки ужались: BANK3 -90 Б, BANK7 -74 Б. Все 8 наборов tests-host проходят; комната 23 в MAME рисуется корректно. Плюс ВРЕМЕННАЯ оснастка замера (маркеры m9..m16, pop_dbg_kind) — она же показала, что пик зелёного блока сидит НЕ в тряске плит, а в запекании тайлов; разбор продолжается, оснастку снять перед закрытием темы. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -452,6 +452,7 @@ int main(void)
|
||||
|
||||
pop_loose_tick(); /* loose-полы: анимация + перерисовка (СЛОЙ ФОНА */
|
||||
/* — ДО Kid, чтобы Kid всегда был поверх плиты) */
|
||||
pop_dbg_m5(); /* ЗАМЕР: pop_loose_tick сделан */
|
||||
pop_process_trobs(cur_room); /* пики/ворота/дверь: продвинуть СОСТОЯНИЕ (порт */
|
||||
/* process_trobs — рисования внутри нет) */
|
||||
if (pop_neigh_dirty) {
|
||||
@@ -478,7 +479,9 @@ int main(void)
|
||||
pop_level_access_end();
|
||||
}
|
||||
}
|
||||
pop_redraw_needed(); /* и разобрать пометки перерисовки тайлов (порт */
|
||||
pop_dbg_m6(); /* ЗАМЕР: pop_process_trobs сделан */
|
||||
pop_redraw_needed();
|
||||
pop_dbg_m7(); /* ЗАМЕР: pop_redraw_needed сделан */ /* и разобрать пометки перерисовки тайлов (порт */
|
||||
/* redraw_needed, seg008:0178) — СЛОЙ ФОНА, до Kid */
|
||||
{ /* ворота соседа слева (room8) видны в col0 — */
|
||||
uint8_t lft = pop_room_link(cur_room, 0); /* редрой шва ТОЛЬКО при изменении openness */
|
||||
|
||||
Reference in New Issue
Block a user