比如這個遊戲,它就消耗了大量的紋理帶寬,因為平均帶寬達到了 4GB/s,而到了幀結尾的部分,峰值已超過 6GB/s。
後續渲染步驟 (Post Processing steps) 對紋理帶寬需求較高是可以理解的,也許您可以在渲染的後序階段把部分帶寬使用於一些特殊的效果處理上面,比如實現光暈和色調映射。但是如果您的遊戲存在很高的紋理讀取帶寬峰值,那麼就需要注意潛在的性能問題了。
對於這個遊戲來說,紋理帶寬的消耗非常高,需要進一步分析。
要分析潛在的紋理帶寬問題,首先我會檢查紋理緩存情況。我的關注點在於紋理的停滯比例,L1 和 L2 緩存未命中的比例。當 L1 緩存未命中所需的紋理數據時,請求會轉向 L2 緩存,然後會再轉向系統內存。每一步都會增加延遲並且提高功耗。L1 的平均未命中比例不應該超過 10%,未命中的峰值比例不應該超過 50%。
這個遊戲在 GPU 系統的數據採集顯示 L1 緩存的平均未命中比例超過了 20%,而峰值已經達到 80% 甚至更高。
可見這些數據的確非常高了。
對於紋理停滯比例較高的典型原因是紋理未壓縮、複雜的過濾操作 (如非等向性過濾),以及紋理未經 mipmap 處理。
為了分析造成紋理緩存未命中的潛在原因,我會觀察非等向性過濾 (anisotropic filtering) 的紋理獲取比例 (屬於移動終端上的耗時操作) 和非基礎級別紋理 (Non Base Level) 的獲取比例。
獲取非基礎級別紋理的比例是對 mipmap 紋理獲取效率的初略估計。當該數字為 0 時,它意味著 GPU 常常訪問最頂級的 mipmap 紋理數據,也就是紋理的 mipmap 鏈中最大的一片或者未進行 mipmap 處理的紋理。
雖然在 2D 遊戲中基本上可以接受這樣的處理,但是在 3D 遊戲中,這就算是問題了。
當渲染 GUI 或者 PostProcessing 期間訪問未經 mipmap 處理的紋理是可以的。但是在其它場景下,這樣的操作會帶來很大的性能損失,也是導致較差數據緩存效果的原因。
事實上,獲取紋理會消耗大量的系統帶寬,同時可能會造成延遲、電池壽命縮短,甚至引起過熱問題進而導致進一步的性能下降。分析紋理行為相關的 GPU 計數數據並解決所發現的問題,能夠更輕易、更大幅度地提升用戶體驗。