青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

歲月流轉(zhuǎn),往昔空明

C++博客 首頁(yè) 新隨筆 聯(lián)系 聚合 管理
  118 Posts :: 3 Stories :: 413 Comments :: 0 Trackbacks

梗概

SALVIA 0.5.2 的優(yōu)化經(jīng)歷是一個(gè)“跌宕起伏”的過程。這個(gè)過程的結(jié)果很簡(jiǎn)單:

在Core 2 Duo T5800(2.0GHz x 2)上,Sponza的性能提升了60%,ComplexMesh性能提升了26%。

 

背景

SALVIA的整個(gè)渲染流程主要是以下幾部分:

  • 根據(jù)Index Buffer獲得需要進(jìn)行變換的頂點(diǎn);
  • 將頂點(diǎn)利用Vertex Shader進(jìn)行變換;
  • 將變換后的頂點(diǎn),輸出成若干個(gè)float4;
  • 將三角形光柵化。SALVIA的光柵化是將三角形拆分成4x4的像素塊若干,不滿的塊有掩碼來處理;
  • 將像素進(jìn)行插值;
  • 插完值后把像素送到Pixel Shader中處理一趟;
  • 處理完的結(jié)果用Blend Shader塞到Back buffer里面去。

用于測(cè)試的場(chǎng)景:

  • Sponza 26萬個(gè)面,20個(gè)左右的Diffuse紋理(1024x1024);
  • PartOfSponza 約200個(gè)面,4個(gè)Diffuse紋理(1024x1024);
  • ComplexMesh 兩萬個(gè)面,無紋理,有個(gè)能量保守的光照。

最初的版本(V1231)中,性能的主要瓶頸在插值階段,各種耗時(shí)林林總總占了一半以上(50% - 70%)。

相比之下其他階段對(duì)性能的影響要么有限,要么沒有多少優(yōu)化空間。所以最近一周的優(yōu)化,就都集中在了“插值”上。

 

插值算法

線性的插值算法常見的實(shí)現(xiàn)有兩種,

第一種是拿UV插值,第二種是用ddx和ddy累積。

UV是先計(jì)算像素的u和v(基本方法是用面積比,不記得就復(fù)習(xí)一下中學(xué)幾何吧),然后用插值公式:

pixel = v0 * u + v1 * v + v2 * (1-u-v)

后者的步驟是選一個(gè)主頂點(diǎn),然后計(jì)算這個(gè)頂點(diǎn)的ddx和ddy,最后用

pixel = v0 + ddx * offset_x + ddy * offset_y

計(jì)算出相應(yīng)頂點(diǎn)。

但是在圖形學(xué)中,我們還需要對(duì)插值進(jìn)行透視修正,獲得在3D空間中線性的插值結(jié)果。

我們將步驟修正到透視空間

先將v0,v1,v2弄到透視空間中,變成projected_v0, projected_v1, projected_v2

對(duì)于UV的插值是

pixel = ( projected_v0*u + projected_v1*v + projected_v2 * (1-u-v) ) / pixel_w

對(duì)于用ddx和ddy的累積公式是:

pixel = ( projected_v0 + projected_ddx * offset_x + projected_ddy * offset_y ) / pixel_w

 

插值算法的選擇

何詠(Graphixer)大神之前也寫了一個(gè)渲染器,比我快許多(大概是4-6倍),用的是UV;

gameKnife大神兩個(gè)禮拜寫成的渲染器,速度比我用五年寫出來的半成品要快7倍,用的辦法是Lerp到Scanline上,再Lerp到像素。

SALVIA采用了累積法:

struct transformed_vertex { float4 attributes[MAX_ATTRIBUTE_COUNT]; };
transformed_vertex projected_corner;

// 計(jì)算角點(diǎn)的坐標(biāo)
projected_scanline_start = projected_v0 + projected_ddx * offset_x + projected_ddy * offset_y; 

// 像素的透視修正值
float inv_w; 

// 最終輸出的4x4個(gè)像素
pixel_input px_in[4][4];

for(int i = 0; i < 4; ++i)
{
  projected_pixel = projected_scanline_start;
  for(int j = 0; j < 4; ++j)
  {
      // 透視空間轉(zhuǎn)換到線性空間并輸出到px_in中
      px_in[i][j] = unproject( projected_pixel );
     // 累加x方向上的值(透視空間)
      projected_pixel += projected_ddx;
  }
  // 累加y方向上的值(透視空間)
  projected_scanline_start += projected_ddy;
}

 

本輪優(yōu)化之前對(duì)插值算法的優(yōu)化嘗試

注意那個(gè)MAX_ATTRIBUTE_COUNT,這個(gè)值通常比較大,在v1231中,它是32。

不過,顯然我們不需要對(duì)所有的屬性進(jìn)行計(jì)算。敏敏在這里運(yùn)用了一點(diǎn)小小的技巧進(jìn)行了優(yōu)化:只計(jì)算必要的屬性。同時(shí),為了減少分支的使用,他甚至用

template <int N>
void sub_n(out, v0, v1 )
{
    for(int i = 0; i < N; ++i) {
       out.attributes[i] = v0.attributes[i] – v1.attributes[i];
    }
}

并配合函數(shù)指針的方法,以促使編譯器展開循環(huán),減少分支。

不過從實(shí)際生成的匯編來看,這個(gè)部分并沒有被展開到期望的形式,可能是編譯器認(rèn)為x86的Branch Predication性能已經(jīng)足夠高了吧。

這個(gè)“優(yōu)化”在v1231中就已經(jīng)具備了。

 

首輪優(yōu)化:unproject函數(shù),operator += 與 operator =

第一個(gè)Profiling是用BenchmarkPartOfSponza和Sponza跑的;unproject,operator +=和operator = 加在一起大約占用了15-20%的時(shí)間。單獨(dú)的unproject

最初的實(shí)現(xiàn)就是普通的標(biāo)量。既不要求對(duì)齊,也沒有使用SIMD。

所以當(dāng)然會(huì)以為用了SIMD后,優(yōu)化效果會(huì)很好。于是在v1232中,中間頂點(diǎn)和像素輸入的分配都以16字節(jié)對(duì)齊,unproj,+=和=也都使用了SSE進(jìn)行了重寫。

從跑分來看,PartOfSponza性能提升了20%。但是,在測(cè)試ComplexMesh和Sponza時(shí),并未發(fā)現(xiàn)幀率有顯著提升。

其實(shí)在進(jìn)行優(yōu)化之前,何詠就告誡過我,因?yàn)楝F(xiàn)代CPU的一些技術(shù),比方說超標(biāo)量啥的,四個(gè)數(shù)據(jù)寬度的SSE和標(biāo)量運(yùn)算相比,就只有50%的性能差距。

并且這些函數(shù)的指令已經(jīng)極為簡(jiǎn)單,瓶頸也很明確的落在計(jì)算指令上。例如Unproject優(yōu)化后,性能焦點(diǎn)就落在_mm_mul_ps上(3.7%),幾無優(yōu)化余地。

 

二輪優(yōu)化:插值算法的調(diào)整

在進(jìn)行第二輪優(yōu)化之前同樣運(yùn)行了一次Profiling。因?yàn)閷?duì)PartOfSponza性能基本滿意,因此這次優(yōu)化的目標(biāo)主要在Sponza上。

排名前幾位的小函數(shù),分別是sub_n,unproj,+= 和tex2D。對(duì)sub_n例行優(yōu)化后,性能沒什么變化。當(dāng)然,這也是意料之中的事情了。

因此,第二輪優(yōu)化便著重考慮在插值算法本身上。

在優(yōu)化之前,我嘗試對(duì)代碼成本做個(gè)粗略的評(píng)估:

在現(xiàn)有算法下,假設(shè)每個(gè)像素有N個(gè)需要插值的屬性,則平均每個(gè)像素有

(corner)3N/16個(gè)讀 + 2N/16個(gè)乘法 + 2N/16個(gè)加法 + N/16個(gè)寫

(x:+=)2N個(gè)讀 + N個(gè)加法 + N個(gè)寫

(x:*)  N個(gè)讀 + 1個(gè)標(biāo)量除法 + N個(gè)乘法 + N個(gè)寫

(y:+=)2N/4個(gè)讀 + N/4個(gè)加法 + N/4個(gè)寫

(y:=) N/4個(gè)讀 + N/4個(gè)寫

因?yàn)槊總€(gè)都是函數(shù)指針,所以這些都是優(yōu)化不掉的。因此首先將一些操作合并了一下,比如把+= 和*合并以減少一下讀寫操作。只可惜效果也不是很明顯。

 

第二刀就砍到算法的頭上。因?yàn)槔奂颖旧硎菫榱藴p少乘法的運(yùn)用,但是這可能帶來了多余的存取開銷。

因此直接套用公式:

pixel = ( projected_v0 + projected_ddx * offset_x + projected_ddy * offset_y ) / pixel_w

這樣就有:3N讀,2N乘法,2N加法,N個(gè)乘法和N個(gè)寫(假設(shè)寄存器夠用的話)。不算Corner的計(jì)算成本,這樣比較一下,就等于是3N/4個(gè)讀,N/2+N個(gè)寫,N/4個(gè)加法來?yè)Q取2N個(gè)乘法的時(shí)間。本來以為作為IO瓶頸的應(yīng)用,這樣可以提高一些性能。不過結(jié)果證實(shí)這個(gè)買賣實(shí)在是很不劃算,整體性能不增反減。

 

三輪優(yōu)化:減少內(nèi)存占用,柳暗花明

雖然所有的操作只針對(duì)已使用的屬性,但是空間上還是浪費(fèi)了許多。

考慮到內(nèi)存占用較大也會(huì)導(dǎo)致一些性能損失,于是將MAX_ATTRIBUTE_COUNT從32下調(diào)到了8。

結(jié)果令人大跌眼鏡。性能瞬間提升了20-30%之多。

再加上SSE也不知道為什么開始發(fā)力了,使用上之后性能大約又有了10-15%的提升。

我猜測(cè)可能是因?yàn)閾Q頁(yè)頻率下降,以及Cache的命中率提升。不過手上沒有VTune這種工具,所以也不太好驗(yàn)證。

 

四輪優(yōu)化:精度敏感性下降的額外紅利

在這輪優(yōu)化之后,PartOfSponza出現(xiàn)了精度問題。因?yàn)橐曞F體的上下左右四個(gè)面都沒有Clip,所以可能會(huì)出現(xiàn)非常大的三角形。這樣累積的時(shí)候一旦起始點(diǎn)選擇的不好,就會(huì)出現(xiàn)比較大的誤差。在之前版本中,使用/fp: precise來減少這一問題出現(xiàn)的機(jī)會(huì)。但是因?yàn)槭褂昧薙SE,也讓這個(gè)問題再難解決。因此我選用了一些辦法,來改善精度問題。在大問題都修正以后,換用/fp: fast來編譯整個(gè)SALVIA,最終也獲得了0-10%左右的性能收益。

 

結(jié)論

對(duì)于運(yùn)算和IO都密集的程序來說,優(yōu)化真可能是牽一發(fā)而動(dòng)全身的問題。比如在我的例子中,所有猜測(cè)是性能瓶頸的地方,都沒有得到預(yù)想中的改善。

倒是在內(nèi)存占用這個(gè)地方無心插柳,才得以柳暗花明,而且還讓別的優(yōu)化方案體現(xiàn)了價(jià)值。所以如果你不像qiaojie大牛那樣對(duì)x86了如指掌,還是要習(xí)慣于從多方面猜測(cè),例如內(nèi)存占用,對(duì)齊或緊縮,計(jì)算強(qiáng)度,訪存密度,并行度等多個(gè)角度進(jìn)行設(shè)想并用實(shí)踐去驗(yàn)證。盡管可能會(huì)遇到很多挫折,但是,只要是直覺上有優(yōu)化的余地,一般都可以找到合適的方案。

posted on 2013-02-11 20:09 空明流轉(zhuǎn) 閱讀(2837) 評(píng)論(2)  編輯 收藏 引用

評(píng)論

# re: SALVIA 0.5.2優(yōu)化談 2013-02-15 23:56 egmkang
跪拜巨巨  回復(fù)  更多評(píng)論
  

# re: SALVIA 0.5.2優(yōu)化談 2014-02-17 23:17 Kitchen020
一直有SALVIA的代碼,最近開始研究,LZ繼續(xù)努力!!  回復(fù)  更多評(píng)論
  


只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲二区免费| 另类欧美日韩国产在线| 久久亚洲影音av资源网| 久久精品国产清高在天天线| 亚洲欧美在线aaa| 欧美一区二区在线观看| 久久综合久久久久88| 欧美成人免费va影院高清| 亚洲国产高清一区| 亚洲欧洲精品一区二区三区不卡| 亚洲激情精品| 亚洲欧美清纯在线制服| 欧美一区国产一区| 欧美成人高清视频| 国产精品久久999| 韩日精品视频一区| 亚洲精选一区| 欧美在线观看日本一区| 欧美激情导航| 亚洲男人影院| 欧美国产成人精品| 国产一区二区中文| 日韩一级裸体免费视频| 久久久91精品国产一区二区三区| 亚洲高清久久| 午夜免费日韩视频| 欧美精品v国产精品v日韩精品| 国产精品久久久一本精品| 亚洲国语精品自产拍在线观看| 亚洲欧美日韩一区二区三区在线| 欧美国产第二页| 久久超碰97人人做人人爱| 欧美图区在线视频| 亚洲精品视频一区| 男人插女人欧美| 欧美一级视频免费在线观看| 欧美精品亚洲二区| 亚洲国产精品va在线看黑人动漫| 久久成人免费网| 亚洲视频精品在线| 欧美日韩久久| 亚洲精品一线二线三线无人区| 久久一本综合频道| 午夜亚洲福利在线老司机| 国产精品国产三级国产aⅴ浪潮 | 亚洲国产精品va在线看黑人| 亚洲欧美日韩国产成人精品影院| 亚洲狠狠丁香婷婷综合久久久| 久久精品国内一区二区三区| 国产欧美综合在线| 欧美一级播放| 午夜精品三级视频福利| 国产精品久久久久久亚洲调教| 一区二区三区欧美| 亚洲精品一区二区网址| 欧美激情一区二区三区全黄| 亚洲精品久久久久| 欧美国产高清| 欧美国产1区2区| 99re6这里只有精品视频在线观看| 欧美不卡视频| 欧美国产一区二区三区激情无套| 日韩亚洲国产精品| 99精品免费视频| 国产精品v一区二区三区| 亚洲在线播放| 性做久久久久久久免费看| 国产欧美日韩视频| 久久午夜羞羞影院免费观看| 久久一区免费| 一区二区三区不卡视频在线观看| av不卡免费看| 国产人妖伪娘一区91| 蜜臀久久99精品久久久久久9 | 欧美日韩国产在线播放| 亚洲图片你懂的| 午夜国产一区| 在线欧美日韩精品| 亚洲精品美女免费| 国产精品视频大全| 老司机成人网| 欧美日韩国产首页在线观看| 亚洲欧美三级伦理| 久久久精品五月天| 一区二区高清视频在线观看| 亚洲直播在线一区| 亚洲国产精品精华液网站| 亚洲伦理在线免费看| 国产欧美一区二区三区沐欲| 欧美高清在线视频| 国产精品亚洲综合天堂夜夜| 麻豆国产精品777777在线| 欧美精品日韩一区| 久久精品99久久香蕉国产色戒| 免费毛片一区二区三区久久久| 亚洲一区二区精品| 久久另类ts人妖一区二区| 在线中文字幕一区| 久久一区免费| 欧美在线|欧美| 欧美理论片在线观看| 亚洲福利视频网| 在线视频日本亚洲性| 曰韩精品一区二区| 亚洲制服少妇| 中文国产成人精品| 欧美成人免费va影院高清| 销魂美女一区二区三区视频在线| 免费观看亚洲视频大全| 久久国产色av| 国产精品日本精品| 亚洲精品一区二区三区婷婷月| 国产一区清纯| 午夜精品成人在线| 亚洲无线一线二线三线区别av| 你懂的网址国产 欧美| 久久免费精品日本久久中文字幕| 国产精品剧情在线亚洲| 日韩视频在线一区二区| 亚洲精品免费一二三区| 久热精品视频在线观看| 久久久女女女女999久久| 国产精品一区二区男女羞羞无遮挡| 亚洲精品极品| 在线亚洲欧美视频| 欧美日韩国产在线播放网站| 亚洲黄色成人| 日韩视频国产视频| 欧美精品免费在线观看| 亚洲国产精品99久久久久久久久| 在线免费精品视频| 麻豆精品在线播放| 亚洲大片在线| 亚洲精品一区二区在线观看| 欧美高清在线播放| 亚洲日韩成人| 亚洲一二三区在线| 国产精品人人爽人人做我的可爱 | 亚洲香蕉视频| 欧美午夜精品久久久久久超碰| 亚洲乱亚洲高清| 亚洲桃色在线一区| 国产精品久久久久三级| 亚洲尤物在线视频观看| 久久激情综合网| 亚洲电影欧美电影有声小说| 美女网站在线免费欧美精品| 亚洲国产成人在线| 亚洲视频每日更新| 国产伦精品一区二区三区视频黑人| 亚洲欧美色婷婷| 美女主播一区| 在线亚洲精品| 国产欧美精品一区二区三区介绍| 欧美一级淫片播放口| 欧美成人精品h版在线观看| 亚洲精品免费一二三区| 欧美婷婷久久| 久久国产福利| 日韩一级精品视频在线观看| 性欧美18~19sex高清播放| 国产一区二区视频在线观看| 免费成人性网站| 亚洲无吗在线| 欧美大片免费观看在线观看网站推荐| 最新成人在线| 国产精品一区二区在线| 久久亚洲精品伦理| 一区二区三区久久| 亚洲欧洲日本在线| 国产精品成人国产乱一区| 欧美一区二区三区啪啪| 亚洲国产成人久久综合一区| 亚洲欧美精品在线观看| 亚洲国产老妈| 国产美女精品视频| 欧美成人在线免费观看| 亚洲在线免费| 亚洲精品美女在线观看| 久久久五月天| 亚洲自拍偷拍福利| 亚洲国产日韩一级| 国产日韩欧美日韩大片| 欧美激情一区二区| 久久视频在线视频| 亚洲一区二三| 亚洲精选一区二区| 欧美电影免费观看高清| 久久精品国产一区二区电影| 中文亚洲免费| 亚洲美女av在线播放| 精品999日本| 国产乱子伦一区二区三区国色天香 | 亚洲欧美第一页| 99精品视频免费| 亚洲黄一区二区| 激情校园亚洲| 国产一区视频在线观看免费| 国产精品久久久久久久久久ktv | 国产精品一区二区三区乱码|