本系列文章是對 http://metalkit.org 上面MetalKit內(nèi)容的全面翻譯和學習.
幾周前,在WWDC2016
,Apple
工程師發(fā)布了一份新的文檔,Metal Best Practices Guide Metal最佳實踐指南,它包含了非常有用的信息,關(guān)于如何在你的Metal
應用中組織代碼來獲得更好的性能.因為文檔是非常全面廣泛的,我們在本文中將只列出主要的概念.一個高效的Metal
應用需要:
- 低
CPU
占用. - 最佳的
GPU
性能. - 連續(xù)的處理器并行計算.
- 高效資源管理.
1 Resource Management 資源管理
1.1 Persistent Objects持久對象
最佳實踐:盡早創(chuàng)建持久對象并重用它們.
Metal
框架提供了幾個協(xié)議來管理那些貫穿你的應用整個生命周期的持久對象.這些對象創(chuàng)建花費很大但通常初始化一次并經(jīng)常重用.不要在每個渲染循環(huán)或計算循環(huán)開始時創(chuàng)建這些對象.
- 先初始化你的Device和Command Queue命令隊列
- 在Build Time創(chuàng)建時間就編譯你的函數(shù)和庫
- 建立Pipelines管線一次并重用它們
- 預告分配資源儲存空間
要了解更多信息,查閱文檔的持久對象章節(jié)Persistent Objects
1.2 Resource Options資源設置
最佳實踐:為你的資源設置合理的儲存模式和紋理使用設置.
Metal
資源必須被合理配置來充份利用調(diào)整內(nèi)存訪問和驅(qū)動器性能優(yōu)化.資源儲存模式允許你為MTLBuffer
和MTLTexture
對象自定義儲存位置和訪問權(quán)限.紋理使用設置允許明確聲明你想要如何使用你的MTLTexture
對象.
- 熟悉設備內(nèi)存模式
- 選擇合理的資源儲存模式(
iOS
和tvOS
) - 選擇合理的資源儲存模式(
OS X
) - 設置合理的紋理使用標志
要了解更多信息,查閱文檔的資源設置章節(jié)Resource Options
1.3 Triple Buffering三重緩沖器
最佳實踐:實現(xiàn)三重緩沖器來更新動態(tài)緩沖器數(shù)據(jù).
動態(tài)緩沖器數(shù)據(jù)指緩沖器內(nèi)儲存的經(jīng)常更新的數(shù)據(jù).強烈推薦實現(xiàn)一個三重緩沖器模型,來避免每幀創(chuàng)建新的緩沖器及最小化幀間處理器閑置時間.
- 防止訪問沖突,減少處理器閑置時間
- 減少內(nèi)存開銷和幀延遲
- 允許命令緩沖器事務時間
- 實現(xiàn)三重緩沖器模型
要了解更多信息,查閱文檔的三重緩沖器章節(jié) Triple Buffering
1.4 Buffer Bindings緩沖器綁定
最佳實踐:用合理的方法來綁定你的緩沖器數(shù)據(jù)到圖形或計算函數(shù).
Metal
提供了若干API
設置來綁定緩沖器數(shù)據(jù)到圖形或計算函數(shù).setVertexBytes:length:atIndex: 方法是最佳選項來綁定大量小于4KB的動態(tài)緩沖器數(shù)據(jù)(瞬時緩沖器)到頂點函數(shù).如果數(shù)據(jù)大于4KB,你應該一次性創(chuàng)建一個MTLBuffer并在需要時更新它的內(nèi)容.
要了解更多信息,查閱文檔的緩沖器綁定章節(jié) Buffer Bindings
Display Management顯示管理
2.1 Drawables可繪制對象
最佳實踐:盡可能短暫的持有可繪制對象.
命令緩沖器在自己被調(diào)度執(zhí)行之前,可以通過presentDrawable方法來調(diào)度drawable的顯示,但是,實際上drawable自己是在命令緩沖器被執(zhí)行完才顯示的.
- 用MetalKit View來獲取Drawable
要了解更多信息,查閱文檔的可繪制對象章節(jié)Drawables section of the documentation.
2.2 Native Screen Scale (iOS and tvOS)原生屏幕比例
最佳實踐:以目標顯示屏的精確像素尺寸來渲染.
你的drawable的像素尺寸應該總是匹配目標顯示屏的精確像素尺寸.這樣可以避免離屏像素渲染,或引發(fā)額外的采樣處理.
- 用MetalKit View來支持原生屏幕比例
要了解更多信息,查閱文檔的原生屏幕比例章節(jié) Native Screen Scal
2.3 Frame Rate (iOS and tvOS)幀率
最佳實踐:對于那些不能維持60 FPS幀率的應用,以一個穩(wěn)定的幀率顯示你的drawable.
iOS
設務的屏幕刷新率是60 Hz
.不能穩(wěn)定在這段時間內(nèi)完成幀渲染的應用,應該設置更低的幀率來避免卡頓.tvOS
的屏幕刷新率一般是60 Hz
,但并不固定.
- 用MetalKit View來支持原生屏幕比例
要了解更多信息,查閱文檔的幀率章節(jié)Frame Rate
3 Command Generation命令生成
3.1 Load and Store Actions加載與儲存動作
最佳實踐:為你的渲染目標設置合理的加載與儲存動作.
在你的Metal
渲染對象上執(zhí)行的動作必須被合理配置,來避免在渲染過程的開始()或xf昂貴或不必要的渲染工作.
- 選擇合理的加載動作
- 選擇合理的儲存動作
- 在渲染過程中評估動作
要了解更多信息,查閱文檔的加載與儲存動作章節(jié)Load and Store Actions
3.2 Render Command Encoders (iOS and tvOS)渲染命令編碼器
最佳實踐:盡可能的合并渲染命令編碼器.
消除不必要的渲染命令編碼器,減少內(nèi)存帶寬占用并提高性能.
- 評估渲染傳遞順序
- 評估采樣依賴
- 評估渲染過程中的動作
要了解更多信息,查閱文檔的渲染命令編碼器章節(jié)Render Command Encoders
3.3 Command Buffers命令緩沖器
最佳實踐:每幀提交盡可能少的命令緩沖器,充份利用GPU
.
命令緩沖器在Metal
中是提交工作的基本單位;它們由CPU
創(chuàng)建并被GPU
執(zhí)行.這種關(guān)系允許你通過調(diào)整每幀提交的命令緩沖器數(shù)量來平衡CPU
和GPU
的工作.
要了解更多信息,查閱文檔的命令緩沖器章節(jié)Command Buffers
3.4 Indirect Buffers間接緩沖器
最佳實踐:如果你的繪制或調(diào)度調(diào)用參數(shù)是由GPU
動態(tài)生成的,應使用間接緩沖器.
間接緩沖器是MTLBuffer
對象,它帶有一個特殊的數(shù)據(jù)布局來代表繪制或調(diào)度命令參數(shù).
- 消除不必要的數(shù)據(jù)傳輸并減少處理器閑置時間
要了解更多信息,查閱文檔的命令緩沖器章節(jié)Indirect Buffers
4 Compilation
4.1 Functions and Libraries函數(shù)和庫
最佳實踐:在build生成時編譯你的函數(shù),并生成你的庫.
編譯Metal Shading Language
源代碼是Metal
應用中耗時的階段之一.Metal
通過允許你在build時編譯圖形和計算函數(shù)并在運行時作為庫加載它們,來縮短時間花費.
- 在build時生成你的庫
- 將函數(shù)放在一個單一的庫里面
要了解更多信息,查閱文檔的函數(shù)和庫章節(jié) Functions and Libraries
4.2 Pipelines管線
最佳實踐:異步build生成你的渲染和計算管線.
擁有多個渲染或計算管線允許你為特定任務使用不同的狀態(tài)配置.異步生成這些管線可以提高性能和并發(fā)數(shù).推薦你提前生成所有已知的管線,避免懶加載.
要了解更多信息,查閱文檔的管線章節(jié)Pipelines
這份指南,還有Metal編程指南 Metal Programming Guide及Metal著色語言指南Metal Shading Language Guide都已經(jīng)更新到iOS 10
, tvOS 10
和OS X 10.12
,它們?nèi)课臋n包含了創(chuàng)建高性能Metal
應用所需的一切.