分析著色器效能

AGI 影格分析器可讓您從其中一個算繪通道中選取繪製呼叫,然後瀏覽「Pipeline」窗格的「Vertex 著色器」區段或「片段著色器」區段,藉此調查著色器。

您會在這裡看到有用的統計資料來自著色器程式碼的靜態分析,以及已編譯為 GLSL 的標準可攜式中繼表示法 (SPIR-V) 組合。您也可以用一個分頁查看原始 GLSL (包含編譯器為變數、函式等項目產生的名稱),這是透過 SPIR-V Cross 去編譯的做法,為 SPIR-V 提供額外的背景資訊。

靜態分析

字幕
圖 1 字幕?

使用靜態分析計數器,即可查看著色器中的低層級作業。

  • ALU 指令:這個計數顯示了在著色器中執行的 ALU 運算 (加法、乘法、除法等) 的數量,很適合用來評估著色器的複雜程度。建議您盡量減少這個值。

    重構一般運算或簡化著色器中的運算,有助於減少所需的指令數量。

  • 紋理指示:這個計數顯示在著色器中進行紋理取樣的次數。

    • 根據取樣來源的紋理類型而定,紋理取樣可能會耗費大量資源,因此將著色器程式碼與「描述元集」一節中的邊界紋理交叉參照,可以針對要使用的紋理類型提供更多資訊。
    • 請勿在對紋理進行取樣時隨機存取,因為這種行為不適用於紋理快取。
  • 分支版本操作說明:這個計數顯示著色器中的分支版本作業數量。將分支版本降到最低,最適合用於 GPU 等平行處理處理器,甚至能協助編譯器尋找其他最佳化功能:

    • 使用 minmaxclamp 等函式,就不必針對數字值進行分支。
    • 測試分支的運算費用。由於這兩個分支版本的路徑都是在許多架構中執行,因此在許多情況下,執行運算速度都會比使用分支時略過計算還要快。
  • 臨時註冊:這類快速且核心暫存器,用於保存 GPU 進行計算所需的中繼作業結果。系統設有運算的暫存器數量限制,GPU 必須使用其他非核心記憶體來儲存中間值,進而降低整體效能。(這項限制會因 GPU 模型而異)。

    如果著色器編譯器執行瞭解散迴圈等運算,使用的臨時暫存器數量可能會高於預期,因此最好將這個值與 SPIR-V 或已編譯的 GLSL 交叉參照,看看程式碼的用途為何。

著色器程式碼分析

調查已解碼的著色器程式碼本身,判斷是否可能有任何改善空間。

字幕
圖 2. 字幕?
  • 精確度:著色器變數的精確度會影響應用程式的 GPU 效能。
    • 請盡可能在變數上使用 mediump 精確度修飾符,因為中度精度 (mediump) 16 位元變數通常比完整精確度 (highp) 32 位元變數更快,效率也更佳。
    • 如果在變數宣告的著色器中找不到任何精確度限定詞,或者在有 precision precision-qualifier​ type​ 的著色器頂端沒有顯示任何精確度限定詞,則該限定詞會預設為完整精確度 (highp)。此外,也請務必查看變數宣告。
    • 基於上述相同原因,也建議將 mediump 用於頂點著色器輸出內容,這樣也能減少記憶體頻寬,且可能需要暫時的登錄用量來執行內插作業。
  • 統一緩衝區:請盡可能縮小「統一緩衝區」的大小 (同時保持對齊規則)。這有助於讓運算更與快取相容,並可能使統一資料獲得提升,可以加快核心登錄作業的速度。
  • 移除未使用的 Vertex 著色器輸出內容:如果您發現片段著色器中未使用的頂點著色器輸出內容,請從著色器中移除,以釋出記憶體頻寬和臨時註冊。

  • 將運算從 Fragment 著色器移至 Vertex 著色器:如果片段著色器程式碼執行的運算,獨立於遮蔽片段的特定狀態 (或可正確內插),則將其移至頂點著色器。這是因為在大多數的應用程式中,頂點著色器的執行頻率比片段著色器低許多。