伺服器端效能查詢
伺服器上的良好轉譯效能對於穩定畫面播放速率和良好的使用者體驗至關重要。 請務必仔細監視伺服器上的效能特性,並視需要優化。 您可以透過專用 API 函式來查詢效能資料。
對於轉譯效能影響最大的是模型輸入資料。 您可以調整輸入資料,如設定模型轉換 中所述 。
用戶端應用程式效能也可能是瓶頸。 如需用戶端效能的深入分析,建議採用 performance trace 。
用戶端/伺服器時間軸
在詳細討論各種延遲值之前,請務必先查看時間軸上的用戶端與伺服器之間的同步點:
此圖顯示如何:
- 姿勢 估計 值是由用戶端以常數 60-Hz 畫面播放速率啟動(每 16.6 毫秒)
- 然後,伺服器會根據姿勢開始轉譯
- 伺服器會傳回編碼的視訊影像
- 用戶端會解碼映射、在映射上執行一些 CPU 和 GPU 工作,然後顯示影像
框架統計資料查詢
畫面格統計資料會提供最後一個畫面的一些高階資訊,例如延遲。 結構中 FrameStatistics
提供的資料會測量在用戶端,因此 API 是同步呼叫:
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
}
}
擷取 FrameStatistics
的物件會保存下列成員:
member | 說明 |
---|---|
LatencyPoseToReceive | 用戶端裝置上相機姿勢估計的延遲,直到此姿勢的伺服器畫面完全可供用戶端應用程式使用為止。 此值包括網路往返、伺服器轉譯時間、視訊解碼和抖動補償。 請參閱 上圖中的間隔 1。 |
LatencyReceiveToPresent | 從接收遠端框架的可用性延遲,直到用戶端應用程式在 CPU 上呼叫 PresentFrame 為止。 請參閱 上圖中的間隔 2。 |
LatencyPresentToDisplay | 在 CPU 上顯示框架直到顯示器亮起的延遲。 此值包括用戶端 GPU 時間、OS 所執行的任何畫面緩衝、硬體重現,以及裝置相依的顯示掃描逾時。 請參閱 上圖中的間隔 3。 |
TimeSinceLastPresent | 後續在 CPU 上呼叫 PresentFrame 之間的時間。 大於顯示持續時間的值(例如 60-Hz 用戶端裝置上的 16.6 毫秒)表示用戶端應用程式未及時完成 CPU 工作負載所造成的問題。 |
VideoFramesReceived | 最後一秒從伺服器收到的畫面數。 |
VideoFrameReusedCount | 裝置上一秒中已接收的畫面數超過一次。 非零值表示由於網路抖動或伺服器轉譯時間過長而必須重複使用和重現畫面。 |
VideoFramesSkipped | 最後一秒已解碼但未顯示在顯示器上的已接收畫面數,因為有較新的畫面已到達。 非零值表示網路抖動導致多個畫面延遲,然後以高載方式抵達用戶端裝置。 |
VideoFramesDiscarded | 非常類似于 VideoFramesSkipped ,但被捨棄的原因是框架已到這麼晚,甚至無法與任何擱置的姿勢相互關聯。 如果發生這個捨棄作業,就會發生一些嚴重的網路爭用。 |
VideoFrameMinDelta | 在最後一秒到達兩個連續畫面之間的最短時間量。 此範圍與 VideoFrameMaxDelta 一起,提供網路或視訊編解碼器所造成的抖動指示。 |
VideoFrameMaxDelta | 在最後一秒到達兩個連續畫面之間的最大時間量。 與 VideoFrameMinDelta 一起,此範圍會指出網路或視訊編解碼器所造成的抖動。 |
所有延遲值的總和通常大於 60 Hz 的可用幀時間。 這沒問題,因為多個畫面會平行執行,而且新的畫面要求會以所需的畫面播放速率啟動,如下圖所示。 不過,如果延遲變得太大,它會影響後期重現 的品質 ,而且可能會危害整體體驗。
VideoFramesReceived
、 VideoFrameReusedCount
和 VideoFramesDiscarded
可用來測量網路和伺服器效能。 低 VideoFramesReceived
值和高 VideoFrameReusedCount
值的組合可能表示網路壅塞或伺服器效能不佳。 高 VideoFramesDiscarded
值也表示網路壅塞。
最後, TimeSinceLastPresent
, VideoFrameMinDelta
和 VideoFrameMaxDelta
提供傳入視訊畫面和本機簡報呼叫變異數的概念。 高變異數表示不穩定的畫面播放速率。
上述值都沒有清楚指出純網路延遲(圖例中的紅色箭號),因為伺服器忙碌轉譯的確切時間必須從往返值 LatencyPoseToReceive
減去。 整體延遲的伺服器端部分是用戶端無法使用的資訊。 不過,下一段說明此值如何透過伺服器的額外輸入來近似,並透過 NetworkLatency
值公開。
效能評定查詢
效能評定查詢 提供有關伺服器上 CPU 和 GPU 工作負載的更深入資訊。 由於資料是從伺服器要求,因此查詢效能快照集會遵循一般非同步模式:
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...
}
});
}
FrameStatistics
與 物件相反, PerformanceAssessment
物件包含伺服器端資訊:
member | 說明 |
---|---|
TimeCPU | 每一畫面的平均伺服器 CPU 時間以毫秒為單位 |
TimeGPU | 每一畫面的平均伺服器 GPU 時間以毫秒為單位 |
使用率CPU | 伺服器 CPU 使用率總計百分比 |
UtilizationGPU | 伺服器 GPU 使用率總計百分比 |
MemoryCPU | 伺服器主要記憶體使用率總計百分比 |
MemoryGPU | 伺服器 GPU 百分比的專用視訊記憶體使用率總計 |
NetworkLatency | 以毫秒為單位的近似平均往返網路延遲。 在上圖中,此值會對應至紅色箭號的總和。 值是藉由從 的值 FrameStatistics 減去實際的伺服器轉譯時間來 LatencyPoseToReceive 計算。 雖然這個近似值不正確,但它會提供一些網路延遲的指示,與用戶端上計算的延遲值隔離。 |
PolygonsRendered | 在一個框架中轉譯的三角形數目。 此數位也包含稍後在轉譯期間被撲殺的三角形。 也就是說,這個數位不會因不同的相機位置而有所不同,但效能可能會因三角形的撲殺率而大幅變化。 |
PointsRendered | 在一個畫面格中轉譯的點數。 與上述相同的撲殺準則,適用于 PolygonsRendered 這裡。 |
為了協助您評估這些值,每個部分都會隨附品質分類,例如 Great、 Good 、 Mediocre 或 Bad 。 此評定計量提供伺服器健康情況的粗略指示,但不應該被視為絕對。 例如,假設您看到 GPU 時間的「平庸」分數。 它被認為是平庸的,因為它接近整體框架時間預算的限制。 不過,在您的案例中,這可能是一個很好的值,因為您要轉譯複雜的模型。
統計資料偵錯輸出
類別是 C# 類別 ServiceStatistics
,包裝在框架統計資料和效能評估查詢周圍,並提供方便的功能,以匯總值或預先建置的字串的形式傳回統計資料。 下列程式碼是顯示用戶端應用程式中伺服器端統計資料的最簡單方式。
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();
}
}
上述程式碼會以下列文字填入文字標籤:
API 會 GetStatsString
格式化所有值的字串,但也可以從 ServiceStatistics
實例以程式設計方式查詢每個單一值。
也會有成員的變體,其會隨著時間匯總值。 請參閱尾碼 *Avg
為 、 *Max
或 *Total
的成員。 成員 FramesUsedForAverage
會指出此匯總已使用多少框架。
API 文件
- C# 轉譯連線。QueryServerPerformanceAssessmentAsync()
- C++ 轉譯連線ion::QueryServerPerformanceAssessmentAsync()