FrameTiming
структура в UnityEngine
Выполнено в:UnityEngine.CoreModule
Описание
Структура, содержащая высокоуровневые CPU и GPU временные рамки и сопровождающие их соответствующие данные.
С помощью структуры FrameTiming можно получить длительность операций CPU и GPU, время их начала и другие важные сведения о производительности.
Используйте следующие свойства FrameTiming для определения вклада CPU и GPU во время кадра:
- cpuFrameTime относится к общему времени кадра CPU. Оно рассчитывается как время между началом кадра и следующим кадром на главном потоке.
- cpuMainThreadFrameTime — время работы главной нити, или общее время между началом кадра и завершением работы главной нити.
- cpuRenderThreadFrameTime относится к времени работы потока рендеринга, или общему количеству времени между первым запросом работы, представленным потоку рендеринга, и временем, когда вызван метод
Present. - cpuMainThreadPresentWaitTime — это время, которое CPU тратит на ожидания завершения
Presentв течение кадра. - gpuFrameTime — время работы GPU, или общее время между работой, переданной GPU, и сигналом, указывающим, что GPU закончил работу для кадра. Общее время включает продолжительность всех активных и пассивных состояний GPU в кадре.
cpuMainThreadPresentWaitTime — это сумма отображаемых блоков [wait], и включает время ожидания Present и целевых кадров в секунду. Труднее вычислить время работы GPU, потому что оно начинается где-то в середине процессов рендеринга сцены и заканчивается в точке синхронизации следующего кадра с предыдущим кадром.
В примере показано, как определить, связан ли кадр CPU или GPU.
using Unity.Profiling; using UnityEngine;
public class ExampleScript : MonoBehaviour { internal enum PerformanceBottleneck { Indeterminate, // Cannot be determined PresentLimited, // Limited by presentation (vsync or framerate cap) CPU, // Limited by CPU (main and/or render thread) GPU, // Limited by GPU Balanced, // Limited by both CPU and GPU, i.e. well balanced }
FrameTiming[] m_FrameTimings = new FrameTiming[1];
void Update() { FrameTimingManager.CaptureFrameTimings(); var ret = FrameTimingManager.GetLatestTimings((uint)m_FrameTimings.Length, m_FrameTimings); if (ret > 0) { var bottleneck = DetermineBottleneck(m_FrameTimings[0]); // Your code logic here } }
static PerformanceBottleneck DetermineBottleneck(FrameTiming s) { const float kNearFullFrameTimeThresholdPercent = 0.2f; const float kNonZeroPresentWaitTimeMs = 0.5f;
// If we're on platform which doesn't support GPU time if (s.gpuFrameTime == 0) return PerformanceBottleneck.Indeterminate;
var fullFrameTimeWithMargin = (1f - kNearFullFrameTimeThresholdPercent) * s.cpuFrameTime;
// GPU time is close to frame time, CPU times are not if (s.gpuFrameTime > fullFrameTimeWithMargin && s.cpuMainThreadFrameTime < fullFrameTimeWithMargin && s.cpuRenderThreadFrameTime < fullFrameTimeWithMargin) return PerformanceBottleneck.GPU;
// One of the CPU times is close to frame time, GPU is not if (s.gpuFrameTime < fullFrameTimeWithMargin && (s.cpuMainThreadFrameTime > fullFrameTimeWithMargin || s.cpuRenderThreadFrameTime > fullFrameTimeWithMargin)) return PerformanceBottleneck.CPU;
// Main thread waited due to Vsync or target frame rate if (s.cpuMainThreadPresentWaitTime > kNonZeroPresentWaitTimeMs) { // None of the times are close to frame time if (s.gpuFrameTime < fullFrameTimeWithMargin && s.cpuMainThreadFrameTime < fullFrameTimeWithMargin && s.cpuRenderThreadFrameTime < fullFrameTimeWithMargin) return PerformanceBottleneck.PresentLimited; }
return PerformanceBottleneck.Balanced; } }
FrameTiming также содержит информацию о временных метках, которая может быть использована для визуализации временных линий кадров или для расчета дельта с другими маркерами.
- frameStartTimestamp: Время CPU, когда кадр впервые начинается.
- firstSubmitTimestamp: Время CPU, когда первоначальная работа подается на GPU в течение кадра (зависит от платформы и API). Различные платформы подают в разное время.
- cpuTimePresentCalled: Время CPU часов в точке Present() вызвана для кадра. Это время, когда Unity заканчивает подачу объектов для рендеринга и сообщает GPU, что кадр может быть представлен пользователю.
- cpuTimeFrameComplete: Время CPU в точке, когда GPU заканчивает рендеринг кадра. На большинстве платформ это значение рассчитывается и равно First Submit Timestamp + Frame GPU time.
Используйте FrameTimingManager.GetCpuTimerFrequency для преобразования временных меток в секунды.
Дополнительные ресурсы: Введение в менеджер времени кадров, FrameTimingManager.
Свойства
| Свойство | Описание |
|---|---|
| cpuFrameTime | Это общее время кадра CPU, рассчитанное как время между концами двух кадров, которое включает все время ожидания и накладные расходы, в мс. |
| cpuMainThreadFrameTime | Общее время между началом кадра и завершением работы главного потока, в мс. |
| cpuMainThreadPresentWaitTime | Время CPU, затраченное последним кадром в ожидании Present на главном потоке, в мсек. |
| cpuRenderThreadFrameTime | Время кадра между началом работы на потоке рендеринга и вызовом Present, в мс. |
| cpuTimeFrameComplete | Это время CPU в точке, когда GPU закончил отображать кадр и прервал CPU. |
| cpuTimePresentCalled | Это время CPU в момент вызова Present для текущего кадра. |
| firstSubmitTimestamp | Это время CPU, когда первое задание было отправлено на GPU. |
| frameStartTimestamp | Это время CPU, когда был запущен кадр. |
| gpuFrameTime | Время GPU для данного кадра, в мс. |
| heightScale | Это был коэффициент масштабирования по высоте системы динамического разрешения (если она использовалась) для данного кадра и связанных с ним кадров. |
| syncInterval | Это был режим vsync для данного кадра и связанных с ним кадров. |
| widthScale | Это был коэффициент масштабирования по ширине системы динамического разрешения (если она использовалась) для данного кадра и связанных с ним кадров. |