Регресс тактов после четырёх фиксов: убран +130 000 в heal и +130 000 в циане
Замер на сцене каскада (ур.13 к.23) ПОСЛЕ багфиксов показал регресс, причём
в том числе в СИНЕЙ фазе, которую фиксы не трогали:
до фиксов после фиксов после этой правки
работа 783 798 1 038 528 873 930
синяя 142 830 275 538 142 830
зелёная 414 456 415 284 417 630
циан 269 538 479 628 379 482
период (растр.) 4 5 4 (один кадр 5)
Разбор синей зондом L (граница «ввод+heal» / «логика») сразу указал место:
логика 88 020 не изменилась, а «ввод+heal» вырос 55 000 -> 187 500. Это
pop_fore_heal чистит ОБЪЕДИНЁННЫЙ ov_mark: кромка потолка (полоса y 0..8) и
оверлеи соседей (64x64 на тайл) от шести кусков сливались в прямоугольник на
полкомнаты.
Правки, каждая с замером:
1. Оверлей соседа рисуется в ОКНЕ = прямоугольник самого куска. Смысл
оверлея — перекрыть кусок, а что лежит вне него, и так нарисовано
правильным фоном. Даёт три вещи разом: пикселей в разы меньше; куски
тайла, не задевающие кусок, отсеиваются предфильтром pop_blit_b даром (это
и есть вертикальный гейт, отдельного не надо); ov_mark становится НЕ НУЖЕН
— всё нарисованное лежит внутри heal-коридора куска, а он чистится каждый
кадр. Для этого заведён ov_suppress.
2. Кромка потолка — тоже без ov_mark: её куски рисуются от dby = 2, то есть
занимают строки 0..2, а помечает её только кусок и только пока достаёт
(mob_y <= 18) — значит она внутри его же коридора.
3. Предусловия перенесены в РЕЗИДЕНТ, до вызова в банк 2: pop_mob_overlay_tile
и разбор пометок живут в других банках, и каждый вызов платит межбанковый
трамплин (~8 900), а условий всего два дешёвых чтения тайла
(pop_tile_code — резидент, ~1 100). Гейты: тайл соседа не пуст и его
габарит пересекается с габаритом куска; для полосы потолка — тайл полосы
не пуст (а он там чаще всего пуст: кусок существует ровно потому, что
плита из своей клетки выпала, и пустой тайл в переднем слое не рисует
ничего).
ОТРИЦАТЕЛЬНЫЙ РЕЗУЛЬТАТ, откачен: сдавать пометки ряда −1 одной МАСКОЙ
вместо до двенадцати отдельных вызовов (один трамплин вместо двенадцати) —
873 930 -> 879 276, то есть хуже. Пометки ставятся редко, а цена копилки и
разбора маски платится всегда.
Итог: все три секции в бюджете 400 000 (синяя 158 880, циан 379 482), зелёная
417 630 — она была такой и ДО фиксов, это не регресс. Период вернулся к 4
растровым кадрам; ровно один логический кадр из 54 идёт за 5 (работа 873 930
при пороге 860 000).
Цена четырёх багфиксов по итогу: +90 000 работы за кадр (+11 %), из них весь
рост в циане.
Тестовый образ теперь всегда собирается LEVEL=1 (решение пользователя:
переход на нужный уровень он делает сам).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1463,8 +1463,16 @@ static void mob_mark_neighbour(const mob_t *m)
|
||||
* сама структура таблиц: кусок идёт в midtable (draw_mobs), а полоса
|
||||
* потолка — в foretable, и та рисуется позже (draw_tables, seg008:1373). */
|
||||
if (m->y <= 18) {
|
||||
pop_set_redraw_fore_above((uint8_t)m->col);
|
||||
if (m->col + 1 <= 9) pop_set_redraw_fore_above((uint8_t)(m->col + 1));
|
||||
/* Пустой тайл полосы потолка не рисует В ПЕРЕДНЕМ СЛОЕ ничего
|
||||
* (bottom_id = 0, FORE_ANY = 0), а пометка стоит потом двух трамплинов
|
||||
* — в банк 7 за разбором пометок и в банк 2 за самой отрисовкой,
|
||||
* ~8 900 такта каждый. А пустой он тут как раз чаще всего: кусок
|
||||
* существует ровно потому, что плита из своей клетки уже выпала.
|
||||
* Проверяем pop_tile_code — он резидентный, ~1 100 такта. */
|
||||
if (pop_tile_code(-1, m->col))
|
||||
pop_set_redraw_fore_above((uint8_t)m->col);
|
||||
if (m->col + 1 <= 9 && pop_tile_code(-1, m->col + 1))
|
||||
pop_set_redraw_fore_above((uint8_t)(m->col + 1));
|
||||
}
|
||||
if (c > 9) return;
|
||||
if (r >= 0 && r <= 2) pop_set_redraw_fore((uint8_t)(r * 10 + c));
|
||||
@@ -1481,11 +1489,27 @@ static void mob_overlay_neighbour(const mob_t *m)
|
||||
int8_t r = pop_y_to_row((int16_t)m->y);
|
||||
int8_t rt = pop_y_to_row((int16_t)(m->y - 18));
|
||||
int8_t c = (int8_t)(m->col + 1);
|
||||
int ytop, ybot;
|
||||
if (c > 9) return;
|
||||
if (r >= 0 && r <= 2)
|
||||
pop_mob_overlay_tile(r, c, r, (int8_t)m->col);
|
||||
if (rt != r && rt >= 0 && rt <= 2)
|
||||
pop_mob_overlay_tile(rt, c, r, (int8_t)m->col);
|
||||
ytop = m->y - (int)mob_spr[2] + 1; /* верх спрайта куска */
|
||||
ybot = m->y;
|
||||
/* ПРЕДУСЛОВИЯ ПРОВЕРЯЕМ ЗДЕСЬ, до вызова в банк 2. pop_mob_overlay_tile
|
||||
* живёт в банке 2, то есть каждый вызов из банка 7 платит межбанковый
|
||||
* трамплин (~8 900 такта); а условий всего два — тайл не пуст и габарит
|
||||
* тайла пересекается с габаритом куска. Оба дешёвые: pop_tile_code —
|
||||
* резидент (~1 100). Замер 2026-08-17: без этого гейта двенадцать
|
||||
* вызовов на шесть кусков стоили ~130 000 в циане, причём большинство
|
||||
* ничего не рисовало.
|
||||
*
|
||||
* Габарит тайла берём ПОЛНЫМ (63*row+2 .. +66) — какая именно часть
|
||||
* соседа окажется поверх куска, решит уже окно клипа внутри. Сужать по
|
||||
* реальной высоте кусков нельзя: у колонн и зеркала база высокая. */
|
||||
if (r >= 0 && r <= 2 && pop_tile_code(r, c) &&
|
||||
ybot >= 63 * r + 2 && ytop <= 63 * r + 66)
|
||||
pop_mob_overlay_tile(r, c, r, (int8_t)m->col, m->x, m->y, mob_spr[2]);
|
||||
if (rt != r && rt >= 0 && rt <= 2 && pop_tile_code(rt, c) &&
|
||||
ybot >= 63 * rt + 2 && ytop <= 63 * rt + 66)
|
||||
pop_mob_overlay_tile(rt, c, r, (int8_t)m->col, m->x, m->y, mob_spr[2]);
|
||||
}
|
||||
|
||||
static void mob_draw_pass(uint8_t pg, uint8_t want_defer)
|
||||
|
||||
Reference in New Issue
Block a user