Реестр: три отрицательных результата по оптимизации проверок
Записаны, чтобы не повторять, и с разбором причины. 1. cd_sig_same блоком (сравнение 10 байт циклом вместо 13 сравнений полей): по листингу короче (1939 -> 1290), на машине хуже 438 978 -> 450 426. Сумма тактов по листингу считает инструкцию один раз, а тело цикла исполняется десять раз. 2. cd_touch_pb (пометка «для блита» из file-scope вместо четырёх аргументов): 438 978 -> 442 242. В зелёной фазе блиты идут пакетным путём, где нужны все четыре значения, а в регистрах они дешевле, чем чтение из статиков. 3. Обёртка pop_cd_hit_slot поверх pop_cd_hit — 1799 против 1318 тактов; помогло только когда сравнение переехало внутрь. Общий урок записан там же: короткий листинг не равно быстрый код, и снятие аргументов со стека помогает не всегда. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -218,6 +218,38 @@
|
|||||||
аргументами — стало ХУЖЕ (1799 тактов Z80 вместо 1318). Снимать аргументы
|
аргументами — стало ХУЖЕ (1799 тактов Z80 вместо 1318). Снимать аргументы
|
||||||
со стека надо у того, кто их читает, а не этажом выше.
|
со стека надо у того, кто их читает, а не этажом выше.
|
||||||
|
|
||||||
|
### Отрицательные результаты 2026-08-19 — НЕ ПОВТОРЯТЬ
|
||||||
|
|
||||||
|
Три попытки подряд сделали ХУЖЕ. Общая ошибка в двух из них — я оценивал
|
||||||
|
правку по СУММЕ ТАКТОВ ИНСТРУКЦИЙ в листинге, а не по реально исполняемому
|
||||||
|
пути.
|
||||||
|
|
||||||
|
**1. `cd_sig_same` блоком вместо тринадцати сравнений.** Снимок был
|
||||||
|
переложен так, чтобы сравнивать непрерывные 10 байт начала `pop_char_t`
|
||||||
|
циклом `do { if (*a++ != *b++) return 0; } while (--i)`. По листингу
|
||||||
|
функция стала короче (1939 → 1290 тактов), а на машине **стало хуже:
|
||||||
|
438 978 → 450 426 (+11 448)**.
|
||||||
|
|
||||||
|
Причина: сумма по листингу считает каждую инструкцию ОДИН раз, а тело
|
||||||
|
цикла исполняется ДЕСЯТЬ раз. Тринадцать линейных сравнений выполняются по
|
||||||
|
разу каждое и выходят раньше на первом же расхождении. **Урок: короткий
|
||||||
|
листинг ≠ быстрый код; цикл надо разворачивать в уме.**
|
||||||
|
|
||||||
|
**2. `cd_touch_pb` — пометка «для блита» из file-scope.** `pop_cd_touch`
|
||||||
|
зовётся из `pop_blit_b` с четырьмя аргументами, хотя тот держит те же
|
||||||
|
значения в `pb_x`/`pb_top`/`pb_w`/`pb_h`. Специализированный вход без
|
||||||
|
аргументов дал **438 978 → 442 242 (+3 264)**.
|
||||||
|
|
||||||
|
Причина: в зелёной фазе блиты идут ПАКЕТНЫМ путём (`draw_tile` открывает
|
||||||
|
`pop_cd_batch`), а там нужны все четыре значения сразу — и в регистрах
|
||||||
|
(`x`, `y` приходят в HL/DE) они дешевле, чем чтение из статиков.
|
||||||
|
**Снятие аргументов со стека помогает не всегда: если значение и так живёт
|
||||||
|
в регистре, статик его туда ещё и загружать заставит.**
|
||||||
|
|
||||||
|
**3. Обёртка `pop_cd_hit_slot` поверх `pop_cd_hit`** (описана в P16):
|
||||||
|
внутри всё равно звала функцию с пятью аргументами и добавила свои — стало
|
||||||
|
1799 тактов вместо 1318. Помогло только когда сравнение переехало внутрь.
|
||||||
|
|
||||||
### P14. Fore-проход персонажа — от 4 122 до 117 570 [замеры 2026-08-19]
|
### P14. Fore-проход персонажа — от 4 122 до 117 570 [замеры 2026-08-19]
|
||||||
|
|
||||||
**Самая НЕСТАБИЛЬНАЯ статья кадра.** Замеры на одной и той же сцене:
|
**Самая НЕСТАБИЛЬНАЯ статья кадра.** Замеры на одной и той же сцене:
|
||||||
|
|||||||
Reference in New Issue
Block a user