6ee66a627d
- Enhanced the `civilization_evolution.gd` script to improve population handling and resource allocation during civilization transitions. - Introduced new functions in `civilization_state.gd` for profile normalization and merging, ensuring consistent population representation across stages. - Updated `evolution_coordinator.gd` to incorporate budget phases for better tracking of simulation performance. - Improved `frame_budget.gd` to monitor maximum slice durations and phases during processing. - Added a new benchmarking tool in `android_benchmark.gd` to measure performance metrics during simulation runs, including frame processing times and throughput. - Created associated scene and resource files for the benchmarking tool to facilitate testing and performance evaluation.
95 lines
16 KiB
Markdown
95 lines
16 KiB
Markdown
# Все объекты, скорость 6
|
||
|
||
Создано скриптом `tests/create_full_benchmark_save.gd`. Пароль нативного сохранения: `qwerty`.
|
||
Генератор не читает и не перезаписывает сохранение игрока.
|
||
|
||
Начальное состояние: 151 запись каталога (включая группы), все 44 стадии правил цивилизаций, все шесть этик на каждой стадии, 1000 когорт (по десять на сущность с временными партиями). У большинства обычных объектов количество равно 6e60, у стадий цивилизаций — 6e20. Пространство и водород имеют количество 1e90, гелий и металлы — 1e80, энергия — 1e100. Возраст — 1e15 лет. Запасов достаточно для требований продвинутых стадий звезд и структур. Оставшиеся сроки жизни когорт покрывают весь срок жизни сущностей, поэтому переходы происходят во время замера.
|
||
|
||
Это искусственный экстремальный сценарий, а не прогноз для обычного сохранения.
|
||
|
||
Машина: Apple M4 Pro, Godot 4.7.2, рендерер Metal Mobile.
|
||
|
||
| Замер | Результат |
|
||
|---|---:|
|
||
| Headless, скорость 6, шесть шагов по 0,5 секунды | 943,936–1221,992 мс на шаг |
|
||
| Среднее время headless-шага | 1122,287 мс |
|
||
| Пропускная способность headless | 0,446 секунды симуляции на секунду CPU |
|
||
| Настоящий UI, страница цивилизаций, 600 кадров | 17,38 FPS |
|
||
| Средний / p95 / максимальный кадр UI | 57,55 / 99,78 / 116,94 мс |
|
||
| Завершенные транзакции | 23 |
|
||
| Запрошенный прирост игрового времени | 3464662,267 лет |
|
||
| Опубликованный прирост игрового времени | 1080000 лет |
|
||
| Пропускная способность с UI | 0,3117 |
|
||
| Накопленный долг за замер | 2384662,267 игровых лет (23,85 реальных секунд на скорости 6) |
|
||
| Записей каталога осталось в конце | 151 |
|
||
|
||
Динамический шаг достигает предела в 0,5 секунды. Рендеринг идет быстрее 5 FPS, но симуляция не успевает за заданным темпом в этом сценарии. На обработку поколений приходится примерно 94% времени CPU. Подготовка цивилизаций занимает в среднем 634 мс на шаг, в том числе дрифт этик — 218 мс, войны — 124 мс; колонизация — 121 мс на шаг. Интервалы профилировщика вложенные и частично перекрываются.
|
||
|
||
## Сравнение оптимизации дрифта (2026-10-05)
|
||
|
||
Замеры сделаны на одном сгенерированном сохранении и одной машине до и после прямого распределения потоков для обычного и колониального дрифта, а также кеширования ставок дипломатии в фиксированной точке. Каждый headless-запуск выполняет шесть последовательных шагов по 0,5 секунды на каждой скорости.
|
||
|
||
| Замер | До | После |
|
||
|---|---:|---:|
|
||
| Средний headless-шаг на скорости 6 | 1122,287 мс | 1018,559 мс |
|
||
| Пропускная способность headless на скорости 6 | 0,446 | 0,491 |
|
||
| Дрифт этик, сумма интервалов за шесть шагов | 1,338 с | 0,643 с |
|
||
| UI, FPS за 600 кадров | 17,38 | 17,04 |
|
||
| Средний / p95 / максимальный кадр UI | 57,55 / 99,78 / 116,94 мс | 58,70 / 102,67 / 114,30 мс |
|
||
| Завершенные UI-транзакции | 23 | 25 |
|
||
| Запрошено / опубликовано игровых лет в UI | 3464662 / 1080000 | 3533627 / 1180000 |
|
||
| Пропускная способность симуляции с UI | 0,3117 | 0,3339 |
|
||
|
||
Средний headless-шаг ускорился примерно на 9,2%, а интервал профиля дрифта этик сократился примерно на 52%. Частота кадров UI практически не изменилась (в этом запуске снизилась примерно на 2%), при этом завершилось больше транзакций и выросла доля опубликованного игрового времени. На скорости 6 стресс-сценарий все еще отстает от реального времени: пропускная способность — около 0,49 секунды симуляции на секунду CPU в headless и 0,33 с UI. Самыми затратными остаются планирование поколений и войны.
|
||
|
||
Прямые пути сохраняют целое население, но разносят малые целочисленные потоки по нескольким последовательным переходам с помощью остатков для каждого источника. Поэтому распределение в отдельном переходе отличается от независимого округленного распределения по матрице 6×6. Ставки дипломатии округляются до сетки фиксированной точки с шагом 1e-9. Целевая регрессия: 769 проверок эволюции цивилизаций, оптимизаций симуляции, границ партий, укрупненных поколений и эволюции кадров; все пройдены.
|
||
|
||
## Последующая оптимизация подготовки поколений и кешей (2026-10-05)
|
||
|
||
На той же нагрузке среднее время headless-шага на скорости 6 снизилось с 1018,559 до 1005,138 мс (примерно на 1,3%). Пропускная способность headless изменилась с 0,491 до 0,497. Суммарные интервалы `generations` близки: 5,703 с и 5,629 с за шесть шагов. Подготовка цивилизаций остается самой затратной измеренной подфазой — 3,130 с. UI также почти не изменился: 17,04 → 17,09 FPS, пропускная способность симуляции — 0,3339 → 0,3351. Улучшение небольшое: арифметика населения в поколениях по-прежнему дорога при сотнях активных когорт и множестве правил цивилизаций.
|
||
|
||
Профиль теперь отдельно показывает `generation_withdrawal` и `generation_products`. Первый интервал занимает 55,5 мс, второй — 120,2 мс за шесть headless-шагов на скорости 6. Эти значения нельзя складывать с общим временем поколений, поскольку интервалы профилировщика вложенные.
|
||
|
||
## Инкрементальная обработка партий новорожденных (2026-10-05)
|
||
|
||
Удалены снимки когорт до и после рождения и последующий полный обход когорт. `append_batch` теперь сразу накапливает поправку на возраст новорожденных при добавлении частей когорт. Финальный замер после повторного использования сумм завершившихся партий в пределах поколения дал 1028,991 мс на headless-шаг скорости 6 и пропускную способность 0,486. В повторных прогонах этой же версии получилось 1005–1011 мс, поэтому при выборке всего в шесть шагов разброс велик, и устойчивое ускорение утверждать нельзя. В UI получилось 17,05 FPS, среднее время кадра 58,66 мс и пропускная способность 0,3342. Новый профиль показывает 319 мс на обработку партий новорожденных за шесть шагов. Это изменение пока не демонстрирует снижения общего времени на этом сохранении; его потенциальная польза относится прежде всего к сценариям с гораздо большим числом когорт на сущность, где прежние обходы росли пропорционально числу когорт.
|
||
|
||
Повторить замеры из родительской папки проекта:
|
||
|
||
```sh
|
||
godot --headless --path Owniverse.GI --script res://tests/create_full_benchmark_save.gd
|
||
godot --headless --path Owniverse.GI --script res://tests/benchmark_saved_state.gd -- Owniverse.GI/tests/artifacts/all_objects_speed6.adventure.json 0.5 profile
|
||
godot --path Owniverse.GI --script res://tests/benchmark_full_ui.gd
|
||
```
|
||
|
||
## Проверка на Android Note8 (2026-10-06)
|
||
|
||
Сборка benchmark установлена отдельным пакетом `com.KIDGameProduction.Owniverse.AndroidBench`, сохранение основной игры не использовалось. Подготовка и декодирование сохранения выполнялись в фоновом потоке; ход и результат записывались в файл приложения. Устройство: Samsung SM-N950F, Android 9. Сценарий: все объекты и цивилизации, скорость 6, 120 кадров (119 интервалов).
|
||
|
||
| Метрика | Результат |
|
||
|---|---:|
|
||
| FPS UI | 1,76 |
|
||
| Средний / p95 / максимальный кадр | 567,28 / 817,54 / 1278,33 мс |
|
||
| Завершенные транзакции за прогон | 1 |
|
||
| Запрошено / опубликовано игрового времени | 1599938,57 / 10000 лет |
|
||
| Доля опубликованного от запрошенного | 0,00625 |
|
||
| Итоговый динамический шаг | 0,2 с |
|
||
|
||
Самый дорогой участок профиля — `generations`: 5,350 с суммарно за единственную завершенную транзакцию; внутри него `civilization_prepare` занял 3,186 с, `wars` — 2,217 с, `civilization_transitions` — 1,034 с. Интервалы вложены, поэтому их нельзя складывать с `generations`. Этот экстремальный сценарий на Note8 не достигает целевых 5 FPS и сильно отстает по игровому времени. Это замер именно полного стресс-сохранения, а не обычного игрового сохранения.
|
||
|
||
### Покадровая уступка в расчётах цивилизаций
|
||
|
||
Добавлены контрольные точки внутри обработки этик, проигравших в войне, падения популяции и выходов между стадиями. Математика и порядок переходов не меняются. На том же Note8 повторный прогон дал 1,87 FPS против 1,76 FPS до изменения (прирост около 6%). Средний кадр сократился с 567 до 535 мс, но p95 остался 630 мс, максимум — 1281 мс. Это слишком малое улучшение для цели 5 FPS.
|
||
|
||
В повторном профиле `generations` заняли 5,166 с, `civilization_prepare` — 3,040 с, войны — 0,985 с, переходы между стадиями — 0,640 с. Профиль не показывает явного трёхкратного ускорения: контрольные точки лучше дробят отдельные подциклы, но главный синхронный участок остается слишком дорогим. Диагностическая сборка для измерения максимального непрерывного участка не завершила прогон на телефоне; при следующем проходе сначала нужно локализовать этот участок, а затем оптимизировать его отдельно.
|
||
|
||
Контрольный запуск UI-бенчмарка на Apple M4 Pro после изменения: 21,51 FPS, средний / p95 / максимальный кадр — 46,49 / 89,62 / 107,19 мс. Этот результат подтверждает отсутствие регрессии на компьютере, но не заменяет Android-замер.
|
||
|
||
### После перехода этик на доли (2026-10-06)
|
||
|
||
Этическое состояние теперь хранит шесть долей `float`, а точное целое население берётся из реестра объектов. Исходы одной стадии сначала собираются по назначениям; доли состояния обновляются после агрегации потоков. Формат сохранения повышен до версии 6; миграции прежних сохранений нет.
|
||
|
||
Финальная APK повторно проверена на Samsung SM-N950F, Android 9, тем же полным сценарием и 120 кадрами. Два последовательных прогона дали **14,57 и 15,02 FPS**, средний кадр — **68,61 и 66,58 мс**, p95 — **113,03 и 123,03 мс**, по одной завершённой транзакции из 119 интервалов. Опубликовано 10 000 лет из 647 331 и 634 134 запрошенных; пропускная способность — 0,01545 и 0,01577. В последнем профиле `generations` заняли 5,120 с, `civilization_prepare` — 3,162 с, войны — 1,026 с, переходы — 0,728 с, дрейф этик — 0,474 с. Самый длинный непрерывный участок составил **458,14 мс** в `deep_copy_and_coarsen`, максимальный кадр — 976 мс. Предыдущий одиночный запуск старой benchmark-сборки показал 1,83 FPS, поэтому сравнивать его с этой парой напрямую нельзя; оба финальных прогона выполнены на одной APK и подтверждают результат около 15 FPS.
|
||
|
||
На компьютере прошли тесты состояния (70), эволюции (555), оптимизаций симуляции (364), индикаторов (63) и жизни (25). Полный набор всё ещё сообщает о двух отказах в `test_descriptions.gd` при обновлении выбранного описания и смене языка; оба относятся к UI-описаниям, а не к модели этик. В логах Android ошибок GDScript/Godot за прогон не найдено.
|