Prestandafrågor på serversidan
Bra renderingsprestanda på servern är avgörande för stabila bildfrekvenser och en bra användarupplevelse. Det är viktigt att övervaka prestandaegenskaperna på servern noggrant och optimera vid behov. Prestandadata kan efterfrågas via dedikerade API-funktioner.
Mest effektfulla för renderingsprestandan är modellens indata. Du kan justera indata enligt beskrivningen i Konfigurera modellkonverteringen.
Programprestanda på klientsidan kan också vara en flaskhals. För en djupgående analys av prestanda på klientsidan rekommenderar vi att du tar en performance trace.
Tidslinje för klient/server
Innan du går in närmare på de olika svarstidsvärdena är det värt att ta en titt på synkroniseringsplatserna mellan klienten och servern på tidslinjen:
Bilden visar hur:
- en poseuppskattning startas av klienten med konstant bildfrekvens på 60 Hz (var 16,6 ms)
- servern börjar sedan återgivningen, baserat på attityden
- servern skickar tillbaka den kodade videobilden
- klienten avkodar avbildningen, utför lite CPU- och GPU-arbete ovanpå den och visar sedan avbildningen
Rama in statistikfrågor
Bildrutestatistik ger viss information på hög nivå för den sista ramen, till exempel svarstid. Data som tillhandahålls i FrameStatistics
strukturen mäts på klientsidan, så API:et är ett synkront anrop:
void QueryFrameData(RenderingSession session)
{
FrameStatistics frameStatistics;
if (session.GraphicsBinding.GetLastFrameStatistics(out frameStatistics) == Result.Success)
{
// do something with the result
}
}
void QueryFrameData(ApiHandle<RenderingSession> session)
{
FrameStatistics frameStatistics;
if (session->GetGraphicsBinding()->GetLastFrameStatistics(&frameStatistics) == Result::Success)
{
// do something with the result
}
}
Det hämtade FrameStatistics
objektet innehåller följande medlemmar:
Medlem | Förklaring |
---|---|
LatencyPoseToReceive | Svarstid från kamerapositionsuppskattning på klientenheten tills en serverram för den här attityden är helt tillgänglig för klientprogrammet. Det här värdet omfattar tur och retur för nätverk, serveråtergivningstid, videodekodning och jitterkompensation. Se intervall 1 i bilden ovan. |
LatencyReceiveToPresent | Svarstid från tillgängligheten för en mottagen fjärrram tills klientappen anropar PresentFrame på processorn. Se intervall 2 i bilden ovan. |
LatencyPresentToDisplay | Svarstid från att presentera en ram på processorn tills skärmen lyser. Det här värdet inkluderar klientens GPU-tid, eventuell bildrutebuffertning som utförs av operativsystemet, maskinvarureprojektion och enhetsberoende visningsgenomsökningstid. Se intervall 3 i bilden ovan. |
TimeSinceLastPresent | Tiden mellan efterföljande anrop till PresentFrame på processorn. Värden som är större än visningstiden (till exempel 16,6 ms på en 60-Hz-klientenhet) indikerar problem som orsakas av att klientprogrammet inte slutför sin CPU-arbetsbelastning i tid. |
VideoFramesReceived | Antalet bildrutor som tagits emot från servern under den sista sekunden. |
VideoFrameReusedCount | Antal mottagna bildrutor under den sista sekunden som användes på enheten mer än en gång. Värden som inte är noll anger att ramar måste återanvändas och återskapas antingen på grund av nätverks jitter eller överdriven serverrenderingstid. |
VideoFramesSkipped | Antal mottagna bildrutor under den sista sekunden som avkodats, men som inte visas på skärmen eftersom en nyare ram har anlänt. Värden som inte är noll anger att nätverks jittering orsakade att flera bildrutor försenades och sedan kom fram till klientenheten tillsammans i en burst. |
VideoFramesDiscarded | Mycket likt VideoFramesSkipped, men anledningen till att tas bort är att en ram kom in så sent att den inte ens kan korreleras med någon väntande pose längre. Om det här ignoreras uppstår det en allvarlig nätverkskonkurration. |
VideoFrameMinDelta | Minsta tid mellan två på varandra följande bildrutor som kommer under den sista sekunden. Tillsammans med VideoFrameMaxDelta ger det här intervallet en indikation på jitter som orsakas antingen av nätverket eller video codec. |
VideoFrameMaxDelta | Maximal tid mellan två på varandra följande bildrutor som kommer under den sista sekunden. Tillsammans med VideoFrameMinDelta ger det här intervallet en indikation på jitter som orsakas antingen av nätverket eller video codec. |
Summan av alla svarstidsvärden är vanligtvis mycket större än den tillgängliga tidsramen vid 60 Hz. Det här är OK eftersom flera bildrutor körs parallellt och nya bildrutebegäranden startas med önskad bildfrekvens, enligt bilden. Men om svarstiden blir för stor påverkar den kvaliteten på den sena fasens reprojection och kan äventyra den övergripande upplevelsen.
VideoFramesReceived
, VideoFrameReusedCount
och VideoFramesDiscarded
kan användas för att mäta nätverks- och serverprestanda. En kombination av ett lågt VideoFramesReceived
värde och ett högt VideoFrameReusedCount
värde kan tyda på nätverksbelastning eller dålig serverprestanda. Ett högt VideoFramesDiscarded
värde indikerar också överbelastning i nätverket.
SlutligenTimeSinceLastPresent
, VideoFrameMinDelta
, och VideoFrameMaxDelta
ge en uppfattning om variansen för inkommande videorutor och lokala närvarande anrop. Hög varians innebär instabel bildfrekvens.
Inget av ovanstående värden ger en tydlig indikation på ren nätverksfördröjning (de röda pilarna i bilden), eftersom den exakta tid då servern är upptagen måste subtraheras från tur och retur-värdet LatencyPoseToReceive
. Serverdelen av den övergripande svarstiden är information som inte är tillgänglig för klienten. I nästa stycke beskrivs dock hur det här värdet approximeras genom extra indata från servern och exponeras via NetworkLatency
värdet.
Frågor om prestandautvärdering
Frågor om prestandautvärdering ger mer detaljerad information om CPU- och GPU-arbetsbelastningen på servern. Eftersom data begärs från servern följer frågan om en ögonblicksbild av prestanda det vanliga asynkrona mönstret:
async void QueryPerformanceAssessment(RenderingSession session)
{
try
{
PerformanceAssessment result = await session.Connection.QueryServerPerformanceAssessmentAsync();
// do something with result...
}
catch (RRException ex)
{
}
}
void QueryPerformanceAssessment(ApiHandle<RenderingSession> session)
{
session->Connection()->QueryServerPerformanceAssessmentAsync([](Status status, PerformanceAssessment result) {
if (status == Status::OK)
{
// do something with result...
}
});
}
I motsats till objektet FrameStatistics
innehåller objektet PerformanceAssessment
information på serversidan:
Medlem | Förklaring |
---|---|
TimeCPU | Genomsnittlig cpu-tid för servern per bildruta i millisekunder |
TimeGPU | Genomsnittlig GPU-tid för servern per bildruta i millisekunder |
UtilizationCPU | Total server-CPU-användning i procent |
UtilizationGPU | Total server-GPU-användning i procent |
MemoryCPU | Total minnesanvändning för servern i procent |
MemoryGPU | Total dedikerad videominnesanvändning i procent av serverns GPU |
Nätverksfördröjning | Den ungefärliga genomsnittliga svarstiden för tur och retur-nätverket i millisekunder. I bilden ovan motsvarar det här värdet summan av de röda pilarna. Värdet beräknas genom att subtrahera den faktiska serveråtergivningstiden från LatencyPoseToReceive värdet för FrameStatistics . Även om den här uppskattningen inte är korrekt ger den en indikation på nätverksfördröjningen, isolerad från de svarstidsvärden som beräknas på klienten. |
PolygonerRendered | Antalet trianglar som återges i en ram. Det här talet innehåller också trianglar som gallras senare under återgivningen. Det innebär att det här antalet inte varierar mycket mellan olika kamerapositioner, men prestandan kan variera drastiskt, beroende på triangelns utgallringshastighet. |
PointsRendered | Antalet punkter i punktmoln som återges i en ram. Samma utslaktningskriterier som nämnts ovan gäller PolygonsRendered här. |
För att hjälpa dig att utvärdera värdena levereras varje del med en kvalitetsklassificering som Great, Good, Mediocre eller Bad. Det här utvärderingsmåttet ger en grov indikation på serverns hälsa, men det bör inte ses som absolut. Anta till exempel att du ser en "medioker" poäng för GPU-tiden. Det anses mediokert eftersom det kommer nära gränsen för den övergripande tidsramen. I ditt fall kan det dock vara ett bra värde, eftersom du återger en komplex modell.
Felsökningsutdata för statistik
Klassen ServiceStatistics
är en C#-klass som omsluter både bildrutestatistiken och frågor om prestandautvärdering och ger praktiska funktioner för att returnera statistik som aggregerade värden eller som en fördefinierad sträng. Följande kod är det enklaste sättet att visa statistik på serversidan i klientprogrammet.
ServiceStatistics _stats = null;
void OnConnect()
{
_stats = new ServiceStatistics();
}
void OnDisconnect()
{
_stats = null;
}
void Update()
{
if (_stats != null)
{
// update once a frame to retrieve new information and build average values
_stats.Update(Service.CurrentActiveSession);
// retrieve a string with relevant stats information
InfoLabel.text = _stats.GetStatsString();
}
}
Koden ovan fyller i textetiketten med följande text:
GetStatsString
API:et formaterar en sträng med alla värden, men varje enskilt värde kan också frågas programmatiskt från instansenServiceStatistics
.
Det finns också varianter av medlemmarna som aggregerar värdena över tid. Se medlemmar med suffixet *Avg
, *Max
eller *Total
. Medlemmen FramesUsedForAverage
anger hur många bildrutor som har använts för den här aggregeringen.
API-dokumentation
- C#-återgivning Anslut ion. QueryServerPerformanceAssessmentAsync()
- C++ Rendering Anslut ion::QueryServerPerformanceAssessmentAsync()