Refactor simulation timing and frame processing logic for improved accuracy and performance
This commit is contained in:
+2
-9
@@ -243,9 +243,7 @@ godot --path Owniverse.GI --script res://tests/benchmark_civilizations.gd -- ui
|
||||
Stage вызывает `evolute_frame`: транзакция получает бюджет 40 мс и уступает
|
||||
следующему кадру внутри создания партий и обработки стадий. Расчёт остаётся
|
||||
на главном потоке, состояние публикуется только после полного завершения.
|
||||
Одна транзакция обрабатывает 0,2 реальной секунды на любой скорости. Запрошенное время хранится отдельно, поэтому отставание не превращается
|
||||
в один всё более тяжёлый шаг. При предельной нагрузке время симуляции может
|
||||
отставать от запрошенного; это не ограничение FPS интерфейса и не удаление событий.
|
||||
Расчёт запускается после накопления 0,2 реальной секунды и обрабатывает весь ожидающий интервал. Время, поступившее во время расчёта, обрабатывается следующим циклом. При перегрузке шаг растёт; пять завершений в секунду остаются целевой частотой, а не гарантией.
|
||||
|
||||
Производство во время транзакции выполняется после её завершения. Запрошенное
|
||||
время, активный интервал, скорость и очередь производства входят в сохранение;
|
||||
@@ -292,12 +290,7 @@ Stage вызывает `evolute_frame`: транзакция получает б
|
||||
1.057. Замер включает сокращение накопленного отставания сохранения;
|
||||
это результат конкретного сценария на Mac, а не гарантия для Android.
|
||||
|
||||
Полный шаг фиксирован: 0,2 реальной секунды на всех скоростях, пять циклов
|
||||
на секунду запрошенного времени. Неполный интервал накапливается. При отставании
|
||||
шаг сохраняется, долг не отбрасывается. Возобновляемая транзакция сохраняет
|
||||
границу из checkpoint. Бюджет кадра остаётся 40 мс. `test_frame_evolution`
|
||||
проверяет расписание всех шести скоростей, сохранение долга и пять циклов
|
||||
на одну секунду.
|
||||
Целевая частота запуска — пять циклов в секунду. Размер шага равен всему накопленному интервалу. Checkpoint сохраняет границу активного расчёта и ожидающее реальное время. Тест проверяет все шесть скоростей, смену скорости, задержку запуска и накопление времени во время расчёта.
|
||||
|
||||
Дипломатический drift использует шесть взвешенных вкладов вместо матрицы
|
||||
пар этик: вес = сумма вкладов + 195 × свой вклад − противоположный вклад.
|
||||
|
||||
@@ -50,7 +50,9 @@ func run():
|
||||
direct.speed = 3
|
||||
check(E.eq(direct.state, sliced.state), "Queued action and speed change survive publication")
|
||||
sliced.evolute_frame(0.001, self)
|
||||
var second_clock: Dictionary = Clock.advance(requested, 0.001, 3)
|
||||
check(not sliced.frame_busy, "Speed change does not bypass real-time cadence")
|
||||
sliced.evolute_frame(0.189, self)
|
||||
var second_clock: Dictionary = Clock.advance(Clock.advance(requested, 0.001, 3), 0.189, 3)
|
||||
var active: Dictionary = sliced.frame_active_clock.duplicate()
|
||||
while sliced.frame_busy: await process_frame
|
||||
direct.evolution.evolute_to_datetime(active.datetime, active)
|
||||
@@ -111,11 +113,17 @@ func run():
|
||||
var behind = fixture()
|
||||
behind.evolute_frame(1.0, self)
|
||||
while behind.frame_busy: await process_frame
|
||||
check(E.eq(behind.state.time.datetime, 20000) and E.eq(behind.frame_clock.datetime, 100000), "Debt keeps the fixed step and preserves all requested time")
|
||||
for cycle in 4:
|
||||
behind.evolute_frame(0.0, self)
|
||||
while behind.frame_busy: await process_frame
|
||||
check(behind.frame_commits == 5 and E.eq(behind.state.time, behind.frame_clock), "One second is processed in exactly five full cycles")
|
||||
check(E.eq(behind.state.time.datetime, 100000) and E.eq(behind.state.time, behind.frame_clock), "Delayed start consumes all elapsed time in one cycle")
|
||||
behind.evolute_frame(0.0, self)
|
||||
check(behind.frame_commits == 1 and not behind.frame_busy, "Consumed interval cannot be processed twice")
|
||||
behind.evolute_frame(0.23, self)
|
||||
behind.evolute_frame(0.53, self)
|
||||
var pending_clock: Dictionary = behind.frame_clock.duplicate()
|
||||
while behind.frame_busy: await process_frame
|
||||
check(E.eq(behind.state.time.datetime, 123000), "Busy transaction keeps its original target")
|
||||
behind.evolute_frame(0.0, self)
|
||||
while behind.frame_busy: await process_frame
|
||||
check(E.eq(behind.state.time, pending_clock), "Next cycle consumes all time accumulated during computation")
|
||||
dispose(behind)
|
||||
print("Frame evolution: %d checks, %d failures" % [checks, failures])
|
||||
quit(1 if failures else 0)
|
||||
|
||||
Reference in New Issue
Block a user