Последовательность выполнения
This article focuses on details of the UNIGINE execution sequence. Here you will find what is happening under the hood of the UNIGINE Engine. For a high-level overview of UNIGINE workflow, see the Engine Architecture article.Эта статья посвящена детальному рассмотрению последовательности выполнения UNIGINE. Здесь вы узнаете, что происходит под капотом UNIGINE Engine. Для общего обзора рабочего процесса UNIGINE см. статью Архитектура двигателя.
The internal code of the UNIGINE engine and the logic of your application that can be extended using plugins written in C++ or C#, are executed in the pre-defined order:Внутренний код движка UNIGINE и логика вашего приложения, которые могут быть расширены с помощью плагинов, написанных в C++ или C#, выполняются в заранее определенном порядке:
- Initialization. During this stage, the required resources are prepared and initialized. As soon as these resources are ready for use, the Engine enters the main loop. Инициализация . На этом этапе подготавливаются и инициализируются необходимые ресурсы. Как только эти ресурсы готовы к использованию, Engine переходит в основной цикл.
Main loop. When UNIGINE enters the main loop, all its actions can be divided into three stages, which are performed one by one in a cycle:Основной цикл . Когда UNIGINE входит в основной цикл, все его действия можно разделить на три этапа, которые выполняются один за другим в цикле:
- Update stage containing all logic of your application that is performed every frameUpdate этап, содержащий всю логику вашего приложения, которая выполняется каждый кадр
- Rendering stage containing all rendering-related operations, physics simulation calculations, and pathfindingRendering этап, содержащий все операции, связанные с рендерингом, вычисления моделирования физики и поиск пути
- Swap stage containing all synchronization operations performed in order to switch between the buffersSwap этап, содержащий все операции синхронизации, выполняемые для переключения между буферами
This cycle is repeated every frame while the application is running.Этот цикл повторяется каждый кадр во время работы приложения.
- Shutdown. When UNIGINE stops execution of the application, it performs operations related to the application shutdown and resource cleanup.Shutdown. Когда UNIGINE останавливает выполнение приложения, он выполняет операции, связанные с завершением работы приложения и очисткой ресурсов.
The following diagram (clickable) represents the main stages of the UNIGINE execution sequence in default Async Rendering physics mode.
Следующая диаграмма (кликните, чтобы увеличить) представляет основные этапы последовательности выполнения UNIGINE в режиме физики Async Rendering, используемом по умолчанию.
Waiting GPUОжидание GPU#
At most times, UNIGINE finishes all its stages in the main loop faster then the GPU can actually render the frame. That is why double buffering is used: it enables to render frames faster by swapping GPU buffers (the back and front ones) into which rendering is performed.В большинстве случаев UNIGINE завершает все этапы основного цикла быстрее, чем графический процессор может фактически отрендерить кадр. Поэтому используется двойная буферизация : она позволяет быстрее рендерить кадры, меняя местами буферы графического процессора (задний и передний), в которые выполняется рендеринг.
When all scripts have been updated and all calculations on the CPU have been completed, the GPU is still rendering the frame calculated on the CPU. So, the CPU has to wait until the GPU finishes rendering the frame and the rendering buffers are swapped. The period of such waiting time is represented by the Waiting GPU counter in the performance profiler.Когда все сценарии обновлены и все вычисления на ЦП завершены, графический процессор все еще отображает кадр, рассчитанный на ЦП. Таким образом, ЦП должен ждать, пока графический процессор не закончит рендеринг кадра и буферы рендеринга не поменяются местами. Период такого времени ожидания представлен счетчиком Waiting GPU в Профилировщике производительности .
If the Waiting GPU time is too high, it may signal that a GPU bottleneck exists, and art content needs to be optimized. But if by that the frame rate is consistently high, it means you still have the CPU resources available to crunch more numbers.Если время Waiting GPU слишком велико, это может сигнализировать о существовании узкого места графического процессора и необходимости оптимизации художественного контента. Но если при этом частота кадров остается стабильно высокой, это означает, что у вас все еще есть ресурсы процессора, доступные для обработки большего количества данных.
How much time has passed from the moment when all scripts have been updated and all calculations on the CPU have been completed, to the moment when the GPU has finished rendering the frame, also depends on whether the vertical synchronization (VSync) is enabled (can be done via the System menu). If VSync is enabled, the CPU waits until the GPU finishes rendering and the vertical synchronization is performed. In this case, the Waiting GPU counter value will be higher.Сколько времени прошло с момента, когда все скрипты были обновлены и все вычисления на CPU были завершены, до момента, когда GPU завершил рендеринг кадра, также зависит от того, включена ли вертикальная синхронизация (VSync) (может быть сделано через Системное меню ). Если VSync включен , ЦП ожидает, пока графический процессор не закончит рендеринг, и будет выполнена вертикальная синхронизация. В этом случае значение счетчика Waiting GPU будет больше.
The four schemes below show different scenarios of CPU and GPU performance with VSync disabled and enabled.На четырех схемах ниже показаны различные сценарии производительности ЦП и ГП с отключенным и включенным VSync.
The first two schemes show calculation and rendering of the frame when VSync is disabled (in both cases the monitor vertical retrace is ignored):Первые две схемы показывают расчет и рендеринг кадра при отключенном VSync (в обоих случаях вертикальный обратный ход луча монитора игнорируется):
- Scheme 1. The CPU calculates the frame faster than the GPU can render it. So, the CPU waits for the GPU (the Waiting GPU time is high).Схема 1. ЦП вычисляет кадр быстрее, чем графический процессор. Итак, CPU ожидает GPU (время Waiting GPU высокое).
- Scheme 2. The CPU calculations are performed slower than the GPU renders the frame. So, the GPU has to wait while the CPU finishes its calculations. In this case, the Waiting GPU time is small.Схема 2. Вычисления CPU выполняются медленнее, чем GPU отрисовывает кадр. Таким образом, графическому процессору приходится ждать, пока процессор завершит свои вычисления. В этом случае время Waiting GPU мало.
Schemes 3 and 4 show calculation and rendering of the frame when VSync is enabled (the monitor vertical retrace is taken into account):Схемы 3 и 4 показывают расчеты и рендеринга кадра , когда VSync включен (вертикальный обратный ход луча монитора учитывается):
- Scheme 3. The CPU calculates the frame faster than the GPU can render it, and the CPU waits for the GPU. However, in this case, both the CPU and the GPU also wait for VSync.Схема 3. ЦП вычисляет кадр быстрее, чем может его обработать графический процессор, и процессор ожидает появления графического процессора. Однако в этом случае и CPU, и GPU также ждут VSync.
- Scheme 4. The CPU calculates the frame slower than the GPU renders it. In this case, the GPU waits not only the CPU finishes its calculations, but also VSync.Схема 4. ЦП вычисляет кадр медленнее, чем его отображает графический процессор. В этом случае GPU ожидает не только завершения вычислений CPU, но и VSync.
Physics and Pathfinding ThreadsПотоки физики и поиска пути#
The engine uses all available threads to update visible nodes simultaneously, and multi-threaded physics (in the asynchronous physics update mode) and pathfinding which is updated in parallel with the rendering stage.Движок использует все доступные потоки для одновременного обновления видимых нод и многопоточной физики (в асинхронном режиме обновления физики) и поиск пути, который обновляется параллельно с этапом рендеринга.
The following scheme illustrates threads in the process of calculation and rendering of a frame with Async Rendering physics mode enabled:На следующей схеме показаны потоки в процессе расчета и рендеринга кадра с включенным режимом физики Async Rendering:
The first physics frame is calculated in parallel with the rendering in the main thread. Then all the rest of the physics frames are updated in the main thread. All the client's code, for example, updatePhysics(), is called in the main thread as well.Первый физический фрейм вычисляется параллельно с рендерингом в основном потоке. Затем все остальные фреймы физики обновляются в основном потоке. Весь клиентский код, например updatePhysics(), также вызывается в основном потоке.
The last two schemes illustrate how physics gets updated in the Before Rendering mode:Последние две схемы иллюстрируют, как обновляется физика в режиме Before Rendering:
In both cases either a CPU or a GPU has to wait for one another to finish its rendering and swap to synchronize. В обоих случаях CPU или GPU должны ждать друг друга, чтобы завершить рендеринг и поменяться местами для синхронизации.
Correlation between Rendering and Physics FrameratesКорреляция между частотой кадров рендеринга и физикой#
The rendering framerate usually varies, while, as we have already mentioned before, physics simulation framerate is fixed. This means that your update() and updatePhysics() functions from the world logic are called with different frequency.Частота кадров рендеринга обычно варьируется, в то время как, как мы уже упоминали ранее, частота кадров моделирования физики остается фиксированной . Это означает, что ваши функции update() и updatePhysics() из мировой логики вызываются с разной частотой.
The picture above describes what happens, when the physics framerate is fixed to 60 FPS, and the rendering framerate varies. In general, there are three possible cases:На рисунке выше показано, что происходит, когда частота кадров физики фиксируется на уровне 60 кадров в секунду, а частота кадров рендеринга меняется. В общем, есть три возможных случая:
- The rendering framerate is much higher. In this case, physical calculations are done once for two or more frames. This does not raise any problems, as positions of moving objects are interpolated between the calculations. The Stable FPS mode is enabled by default to avoid framerate jumping and dropping (see the detailed explanation in the following section).Частота кадров рендеринга намного выше . В этом случае физические расчеты выполняются один раз для двух или более кадров. Это не вызывает никаких проблем, поскольку положения движущихся объектов интерполируются между расчетами. Режим Stable FPS включен по умолчанию, чтобы избежать скачков и падений частоты кадров (см. подробное объяснение в следующем разделе).
- The rendering framerate is the same or almost the same. This situation is also ok, the calculations are performed once per frame; the physics keeps pace with the graphics and vice versa.Частота кадров при рендеринге такая же или почти такая же. Это тоже нормально, расчеты производятся один раз за кадр; физика идет в ногу с графикой и наоборот.
The rendering framerate is much lower. This is where problems begin. First, as you see from the picture, the physics should be calculated twice or even more times per frame, and that does not speed up the overall rendering process. Second, you cannot set the physics framerate too low, as in this case the calculations will lose too much precision.Частота кадров рендеринга намного ниже. Здесь начинаются проблемы. Во-первых, как видно из рисунка, физика должна вычисляться дважды или даже больше за кадр, и это не ускоряет общий процесс рендеринга. Во-вторых, вы не можете установить слишком низкую частоту кадров физики, так как в этом случае потеря точности расчетов будет слишком велика.
There is no point in setting the number of iterations too high. UNIGINE checks whether the next iteration can be performed within physics budget limit, and if not, it is delayed and moved to the next rendering frame.Нет смысла устанавливать слишком большое количество итераций. UNIGINE проверяет, можно ли выполнить следующую итерацию в рамках бюджета физики, а если нет, он задерживается и переходит к следующему кадру рендеринга.
Stable FPSСтабильный FPS#
When the application's rendering framerate is higher than the physics updates, some frames with physics updates will take more time to calculate. This results in application's framerate jumps and drops which can lead to unstable simulations (especially with input and interactivity involved).Когда частота кадров рендеринга приложения выше, чем у обновлений физики, для расчета некоторых кадров с обновлениями физики потребуется больше времени. Это приводит к скачкам и падению частоты кадров приложения, что может стать причиной нестабильной симуляции (при наличии интерактивности и обработки пользовательского ввода).
To make the framerate more stable, the Stable FPS feature is enabled by default. It adds an Idle state if the current frame took less than the previous one (usually due to lack of Physics calculations). This ensures that each frame takes the same amount of time effectively eliminating framerate's pulsation.Чтобы сделать частоту кадров более стабильной, по умолчанию включена функция Stable FPS. Она добавляет состояние Idle, если текущий кадр занял меньше времени, чем предыдущий (обычно из-за отсутствия физических расчетов). Это гарантирует, что каждый кадр занимает одинаковое количество времени, эффективно устраняя пульсацию частоты кадров.
You can switch this feature off in case your application is used for machine learning or for grabbing frame sequences (Video Grabber), when smoothness is not important.Вы можете отключить эту функцию, если ваше приложение используется для машинного обучения или для захвата последовательностей кадров (Video Grabber), когда плавность не важна.
Synchronizing Engine FPS with Physics OneСинхронизация частоты кадров движка с обновлением физики#
As it was mentioned, in case the Engine framerate is higher than the physics one, the results of physics calculations are interpolated between the frames. But you can enable physics to be calculated each rendered frame by synchronizing the Engine framerate to the physics one (setting the SyncEngineUpdateWithPhysics flag via code). In this mode, there is no twitching of physical objects if they have non-linear velocities. This flag has no effect if the Engine FPS is lower than the physics one.Как уже упоминалось, в случае, если частота кадров движка выше, чем физическая, результаты физических расчетов интерполируются между кадрами. Но вы можете включить вычисление физики для каждого визуализированного кадра, синхронизируя частоту кадров движка с физической (установив флаг SyncEngineUpdateWithPhysics из кода). В этом режиме нет подергивания физических объектов, если они имеют нелинейные скорости. Этот флаг не действует, если Engine FPS ниже физического.