垂直同步、繪製效率、顯示器刷新頻率與幀率

轉:https://blog.csdn.net/leonwei/article/details/7998412

 

從後緩存到顯示器      

最近在看D3D的架構,在這過程中對幀率這個一直認爲很簡單的東西有了更多的理解。在過去看來,幀率就是顯卡渲染一幀所用時間的倒數,現在看來遠遠不是這個樣子。


要真正理解這個問題要從繪製數據從顯存中到屏幕的這一個過程來說起,下圖就是這個過程

 
 

              顯存中存在前後緩存,前緩存就是屏幕上最終看到的像素,而後緩存是繪製使用,後緩存繪製好一幀,通常就交換一次,寫給前緩存,而顯示器則從前緩存不斷的讀取數據。

 

交換幀率與刷新幀率

              通常我們很在意渲染的效率,其實就是繪製的效率,這就是圖中的f1,也成爲交換幀率,f1決定了顯卡一秒能繪製多少次,以前一直以爲這就是用戶的幀率了,其實不是,因爲還有其他因素。

              我們看到顯示器讀取前緩存也存在一個頻率,即f2,f2也被稱爲顯卡的刷新頻率,即顯卡按照多少的頻率去講前緩存的數據給顯示器繪製一次,它不管前緩存的數據是否是新的還是舊的。由此可見我們最終用戶看到的幀率是f1 和 f2的共同結果。實際的幀率f應該表述爲顯示器所能表現的緩存交換幀率,即在1秒內有多少個後緩存的傳遞到了顯示器。這樣看f=min(f1,f2),即受這兩個幀率的制約了。比如說你渲染很快,一秒繪製60次,但是顯卡一秒只想顯示器刷30次,那幀率最高也只有30,再比如你渲染很慢,因爲模型特別大,一秒畫10次,顯示器一秒刷60次,那用戶看到的實際幀率也只有10。到這裏似乎幀率是被這兩者決定的,但是其實還不是這樣。

 

垂直同步與幀率

              從圖中可以看到一點就是前緩存處於被後緩存寫而被顯示器讀的狀態,那麼這過程就極有可能發生讀寫衝突,而顯示器的繪製是從上到下一行行刷新的,一種典型的情況就是顯示器在讀這一幀時前緩存被寫入新的下一幀數據,那麼顯示器的上部分和下部分將顯示不同幀的畫面,這就是常出現的“畫面撕裂”現象,他就是因爲緩存交換太快不等顯示器讀完而造成的。

爲了解決這個現象,引入了“垂直同步”的相關技術,垂直同步就是指顯示器從上到下繪製一個完整幀的畫面的一個過程,在這個過程中,顯卡保證不去改變前緩存,如果這過程繪製好一幀,那麼後緩存發現前緩存在被讀取就不進行交換操作,這樣的結果會保證顯示器繪製不被撕裂,但是也帶來了另一個問題,就是卡幀率,因爲正常的交換幀率被顯示器的垂直同步各種打斷掉,交換幀率大大降低,降低最終幀率。

              看來垂直同步與不垂直同步是兩個極端,他們分別代表着最高的畫面完整度與最高的幀率。所以在實踐中就產生了很多種折中的辦法,就是允許顯卡最多在n幀刷新中只打斷一次緩存交換,n越大越接近完全不用垂直同步,幀率越高,n越小越接近垂直同步,撕裂現象概率越小。垂直同步、不垂直同步和幾種折中其實就對應了D3D9的交換參數的D3DPRESENT_DONOTWAIT、D3DPRESENT_INTERVAL_IMMEDIATE和D3DPRESENT_INTERVAL_ONE(~FOUR)。那麼最終的幀率f應該接近與min{f1-min{f1,f2}/(1+n),f2},通常f2都是足夠大的。

 

           所以幀率不僅與交換幀率、刷新幀率有關,還與垂直同步策略有關,所以我們可以看到一些玩家的遊戲中關閉垂直同步會卡機,也有一些玩家打開垂直同步會降低幀率,就是這個原因。

 

顯存

              當然我們看到垂直同步會制約幀率的時候,是因爲我們這個圖中的的前緩存存只有一處,處於讀寫衝突狀態,那麼會想只要讓顯存不存在這種狀態不就行了嗎,那需要顯存非常大,後緩存是生產者,顯卡是消費者,前緩存如果足夠的大(可以分成n多塊),那麼生產者就有可能不用顧忌的往緩存上堆新東西,事實上完全的不存在衝突是不太可能的,因爲顯存的大小永遠存在一個限制,只要緩存大小有限制,就必然可能出現生產者和消費者的衝突,存在衝突,要麼選擇生產者等消費者(生產降低,即幀率降低),要麼消費者拿到的東西會紊亂(即撕裂),但是顯存越大,這種潛在的衝突的可能性就越小,問題就越容易避免。

              所以我麼看到顯卡顯存較大的客戶端及時完全關閉垂直同步(即理論最大幀率)也不太容易撕裂,或者完全打開垂直同步幀率還是非常高,顯存不僅有利於繪製也有利於解決前緩存衝突提高幀率。

              基於這些思考,所以在選擇渲染策略時,一定要充分考慮垂直同步的策略,根據潛在用戶的硬件、遊戲的繪製效率、刷新效率一起考慮,知道幀率是由繪製效率,顯卡刷新效率和垂直同步策略三者共同決定的。在D3D9中微軟推薦使用的垂直同步策略時D3DPRESENT_INTERVAL_ONE,即最接近完全垂直同步的折中策略,即最多在一次顯卡刷新中打斷一次緩存交換,實際幀率應該是接近於f1/2,如果最終用戶看到的要在30幀的話,z在f2是60的情況下,那麼f1要在60幀以上。
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章