Add comprehensive tests and optimizations for simulation and UI performance
- Introduced a new benchmark save script to create a stress test scenario with extreme values for simulation performance. - Added a full UI benchmark script to measure frame rates and performance metrics during UI interactions. - Implemented tests for coarse generations to ensure population transitions are handled correctly. - Created tests for extra parameters to validate the loading and application of configuration settings. - Developed simulation optimization tests to verify the efficiency of population drift and rounding mechanisms. - Added split optimization tests to ensure accurate allocation and rounding behavior in population management. - Included startup parameter tests to confirm the correct initialization of global parameters before scene readiness. - Enhanced the audit rounding ledger to compare selective and full rounding results for consistency.
This commit is contained in:
+109
@@ -1,5 +1,24 @@
|
||||
# Проверки поэтапного переноса из Owniverse.U
|
||||
|
||||
`test_simulation_optimizations.gd` сравнивает прямые формулы дрейфа с прежней
|
||||
матрицей, включая целые количества больше E27 и накопленные остатки.
|
||||
Тестовый ledger сверяет выборочное округление с полным на каждом поколении
|
||||
нагруженной симуляции. `test_ui_updates.gd` проверяет обновление по публикации,
|
||||
выбору объекта и изменению параметров мира, а также пропуск повторных расчётов
|
||||
для неизменившегося состояния.
|
||||
|
||||
Динамический размер партий проверяется в `test_batch_boundaries.gd`: скорости
|
||||
1–6, сохранение больших целых количеств и дробных остатков, повторное
|
||||
укрупнение и снижение скорости. Высокие скорости допускают приближение
|
||||
времени переходов; сравнение со старым состоянием целиком не является
|
||||
проверкой эквивалентности такого режима.
|
||||
|
||||
`test_coarse_generations.gd` проверяет отсутствие повторного перехода C0.0,
|
||||
C0.1 и C0.2 внутри одного интервала, старое смещение сетки партий,
|
||||
продолжение эволюции в следующем интервале, большие целые количества и
|
||||
дробные остатки. `test_frame_evolution.gd` сравнивает целый и разбитый по
|
||||
кадрам расчёт, включая возобновление сохранённого незавершённого шага.
|
||||
|
||||
## Производительность на сохранении
|
||||
|
||||
```sh
|
||||
@@ -205,3 +224,93 @@ Stage вызывает `evolute_frame`: транзакция получает б
|
||||
15.9 FPS (максимальный кадр 98 мс), большие количества 17.5 FPS (106 мс),
|
||||
много партий 16.3 FPS (97 мс).
|
||||
Это FPS отрисовки, а не число завершённых транзакций симуляции в секунду.
|
||||
|
||||
Индекс партий переиспользуется внутри одной транзакции, отдельно для каждого
|
||||
массива партий. Замена массива при изъятии или переход к другому состоянию
|
||||
сбрасывает индекс. Сортировка выполняется при нарушении порядка новых окон,
|
||||
а не после каждого добавления в уже существующее окно. `test_batch_boundaries`
|
||||
проверяет объединение, раннюю вставку, замену массива и изоляцию состояний.
|
||||
На копии текущего сохранения с 785 партиями шесть шагов на скорости 6:
|
||||
среднее время 167 → 145 мс; полное состояние после шести шагов совпало точно.
|
||||
|
||||
Следующий этап исключает арифметическую работу при прибавлении нуля,
|
||||
временные знаменатели при умножении целых блоков и нулевые вклады этик.
|
||||
На той же копии сохранения среднее время шага скорости 6 снизилось с 145
|
||||
до 138 мс; полный результат после шести шагов совпал с исходным состоянием.
|
||||
Тест появления разума задаёт свой progress явно, поскольку проверяет
|
||||
сохранение хозяина планеты, а не актуальное значение коэффициента баланса.
|
||||
|
||||
Следующие шесть оптимизаций: однократное изъятие умирающих партий;
|
||||
поверхностные снимки неизменяемых таблиц связей; пропуск планирования
|
||||
цивилизаций без переходов; кэш нормализованных этик и произведений поклонения;
|
||||
пропуск укрупнения для нуля/одной партии; кэш вероятностей переходов.
|
||||
Кэши принадлежат миру и не входят в сохранение. Изменение количества,
|
||||
этик, коэффициентов правил или модификаторов обнаруживается по значениям.
|
||||
Суммирование поклонения сохраняет прежний порядок дробных операций.
|
||||
`test_simulation_optimizations` проверяет также обновление этих кэшей.
|
||||
|
||||
Полное состояние совпало с реализацией до этих шести изменений после каждого
|
||||
из восьми шагов на скоростях 1, 4 и 6, отдельно на большом фрагментированном
|
||||
сценарии и на диагностической копии сохранения (48 сравнений).
|
||||
На M4 Pro шесть шагов по 0.1 секунды скорости 6: 103.3 мс первый,
|
||||
70.9–76.0 мс последующие; пропускная способность без UI 1.278.
|
||||
Замер 600 кадров с реальным UI: 12.24 FPS, p95 97.16 мс, максимум 104.86 мс,
|
||||
520 завершённых транзакций, отношение обработанного времени к поступившему
|
||||
1.057. Замер включает сокращение накопленного отставания сохранения;
|
||||
это результат конкретного сценария на Mac, а не гарантия для Android.
|
||||
|
||||
Адаптивный шаг на скоростях 4–6 выбирает 0.1, 0.2 или 0.5 реальной секунды.
|
||||
Долг больше двух шагов повышает ступень, меньше половины шага понижает её.
|
||||
Шаг ограничен доступным запрошенным временем. Скорости 1–3 сохраняют 1/60;
|
||||
смена скорости сбрасывает ступень. Возобновляемая транзакция сохраняет точную
|
||||
границу из checkpoint, адаптация применяется к следующей транзакции.
|
||||
Бюджет кадра остаётся 40 мс; ширина временных партий не меняется.
|
||||
`test_frame_evolution` проверяет ступени, гистерезис, сохранение долга,
|
||||
переключение скорости, возобновление и совпадение с прямым расчётом того же шага.
|
||||
На свежей диагностической копии сохранения с долгом 407.79 млн лет:
|
||||
600 кадров реального UI на M4 Pro дали 18.05 FPS (p95 92.91 мс,
|
||||
максимум 122.45 мс), поступило 3.335 млн лет, обработано 6.480 млн:
|
||||
пропускная способность 1.943 вместо 0.787 при фиксированном шаге 0.1.
|
||||
Разбиение времени влияет на дискретные производство и глобальные параметры;
|
||||
адаптивные шаги не обещают совпадения результата с последовательностью 0.1.
|
||||
|
||||
Дипломатический drift использует шесть взвешенных вкладов вместо матрицы
|
||||
пар этик: вес = сумма вкладов + 195 × свой вклад − противоположный вклад.
|
||||
Для колониальной матрицы коэффициенты 9, 951 и 5 соответственно.
|
||||
Целая численность и механизм сохранения ошибок распределения не меняются,
|
||||
но порядок операций над дробными весами отличается от матричного варианта.
|
||||
Тест сравнивает с матрицей на точно представимых коэффициентах и проверяет
|
||||
целочисленное сохранение популяций до 1e40 на десятичных коэффициентах.
|
||||
Пустые популяции пропускают drift; численность выходов суммируется один раз.
|
||||
На профильной копии при шаге 0.5 число вызовов снизилось 1038 → 849
|
||||
за шесть шагов, но время drift осталось около 303 мс суммарно;
|
||||
заметного ускорения полного расчёта в этом сценарии не зафиксировано.
|
||||
|
||||
`test_split_optimizations.gd` сравнивает распределение и все сохранённые
|
||||
остатки с прежним scalar split в последовательных вызовах: пустые ветви,
|
||||
единственная ветвь, равные веса, десятичные веса, положительные/отрицательные
|
||||
остатки, количества до 1e80. Также проверяет grouped mul_div против scalar.
|
||||
Split переиспользует разложение количества и знаменателя между ветвями,
|
||||
кэширует ключи остатков (не более 512 наборов) и получает веса дрифта массивом.
|
||||
Вторая нормализация пропускается только при целых долях с нужной суммой:
|
||||
при дробях даже единичное отношение может изменить округление, поэтому
|
||||
прежний путь сохраняется. Единственная положительная ветвь обрабатывается
|
||||
напрямую только при целом количестве, неотрицательных весах и нулевых остатках.
|
||||
На профильной копии время drift за шесть шагов 0.5 снизилось примерно
|
||||
303 → 287 мс, но общее время осталось около 1.31 секунды.
|
||||
|
||||
Обычный drift сокращает целое количество из отношения
|
||||
count*weight/(200*count), колониальный — из отношения с 1000.
|
||||
Целая часть делится на малый знаменатель; для дроби используются исходные
|
||||
масштабированные числитель и знаменатель, чтобы сохранить float округление.
|
||||
`test_split_optimizations` проверяет совпадение со scalar mul_div до 1e80.
|
||||
Производство новорождённых сохраняет только created_from → amount вместо
|
||||
глубокой копии партий. Повторное мгновенное рождение с теми же сроками,
|
||||
длительностью и сеткой сразу добавляется в найденную партию.
|
||||
Индекс ближайшей границы позволяет повторным проходам пропускать будущие
|
||||
партии; замена массива, добавление и масштабирование сбрасывают индекс.
|
||||
Тест границ проверяет объединение и сброс обоих индексов.
|
||||
Адаптивный шаг дополнительно учитывает сглаженное отношение реальной
|
||||
длительности транзакции к обработанному времени. Если отношение выше 0.85
|
||||
и долг больше одного шага, ступень увеличивается раньше порога двух шагов.
|
||||
Долг и граница сохраняются как прежде; измерения являются временным кэшем.
|
||||
|
||||
Reference in New Issue
Block a user