當前位置:
首頁 > 知識 > 利用GPGPU計算大規模群落模擬行為

利用GPGPU計算大規模群落模擬行為

前言

在今年6月的Unite Europe 2017大會上 Unity 的CTO Joachim Ante演示了未來Unity新的編程特性——C# Job系統,它提供了編寫多線程代碼的一種既簡單又安全的方法。Joachim通過一個大規模群落行為模擬的演示,向我們展現了最新的Job系統是如何充分利用CPU多核架構的優勢來提升性能的。

但是吸引我的並非是C# Job如何利用多線程實現性能的提升,相反,吸引我的是如何在現在還沒有C# Job系統的Unity中實現類似的效果。

利用GPGPU計算大規模群落模擬行為

為何Joachim 要用這種大規模群落行為的模擬來宣傳Unity的新系統呢?

其實相對來說複雜的並非邏輯,這裡的關鍵詞是「大規模」——在他的演示中,實現了20,000個boid的群體效果,而更牛逼的是幀率保持在了40fps上下。

事實上自然界中的這種群體行為並不罕見,例如大規模的鳥群,大規模的魚群。

利用GPGPU計算大規模群落模擬行為

在搜集資料的時候,我還發現了一位優秀的水下攝影師、加利福尼亞海灣海洋計劃總監octavio aburto的個人網站上的一些讓人驚嘆的作品。

利用GPGPU計算大規模群落模擬行為

圖片來自Octavio Aburto

利用GPGPU計算大規模群落模擬行為

圖片來自Octavio Aburto

而要在計算機上模擬出這種自然界的現象,乍看上去似乎十分複雜,但實際上卻並非如此。

查閱資料,可以發現早在1986年就由Craig Reynolds提出了一個邏輯簡單,而效果很贊的群體模擬模型——而作為這個群體內的個體的專有名詞boid(bird-oid object,類鳥物)也是他提出的。

簡單來說,一個群體內的個體包括3種基本的行為:

  • Separation:顧名思義,該個體用來規避周圍個體的行為。

    利用GPGPU計算大規模群落模擬行為

  • Alignment:作為一個群體,要有一個大致統一的前進方向。因此作為群體中的某個個體,可以根據自己周圍的同伴的前進方向獲取一個前進方向。

    利用GPGPU計算大規模群落模擬行為

  • Cohesion:同樣,作為一個群體肯定要有一個向心力。否則隊伍四散奔走就不好玩了,因此每個個體就可以根據自己周圍同伴的位置信息獲取一個向中心聚攏的方向。

    利用GPGPU計算大規模群落模擬行為

以上三種行為需要同時加以考慮,才有可能模擬出一個接近真實的效果。


Vector3 direction = separation+ alignment + (cohesion - boid.position).normalized;

可以看出,這裡的邏輯並不複雜,但是麻煩的問題在於實現這套邏輯的前提是每個個體boid都需要獲取自己周圍的同伴信息。

因此最簡單也最通用的方式就是每個boid都要和群落中的所有boid比較位置信息,獲取二者之間的距離,如果小於閾值則判定是自己周圍的同伴。而這種比較的時間複雜度顯然是O(n2)。因此,當群體是由幾百個個體組成時,直接在cpu上計算時的表現還是可以接受的。但是數量一旦繼續上升,效果就很難保證了。

利用GPGPU計算大規模群落模擬行為

當然,在Unity中我們還可以利用它的物理組件來獲取一個boid個體周圍的同伴信息:


Physics.OverlapSphere(Vector3 position, float radius, int layerMask);

這個方法會返回和自己重疊的對象列表,由於unity使用了空間劃分的機制,所以這種方式的性能要好於直接比較n個boid之間的距離。

利用GPGPU計算大規模群落模擬行為

但是即便如此,cpu的計算能力仍然是一個瓶頸。隨著群體個體數量的上升,性能也會快速的下降。

GPU的優勢

既然限制的瓶頸在於CPU面對大規模個體時的計算能力的不足,那麼一個自然的想法就是將這部分計算轉移到更擅長大規模計算的GPU上來進行。

CPU的結構複雜,主要完成邏輯控制和緩存功能,運算單元較少。與CPU相比,GPU的設計目的是儘可能的快速完成圖像處理,通過簡化邏輯控制並增加運算單元實現了高性能的並行計算。

利用GPGPU計算大規模群落模擬行為

利用GPU的超強計算能力來實現一些渲染之外的功能並非一個新的概念,早在十年前nvidia就為GPU引入了一個易用的編程介面,即CUDA統一計算架構,之後微軟推出了DirectCompute——它隨DirectX 11一同發布。

和常見的vertex shader和fragment shader類似,要在GPU運行我們自己設定的邏輯也需要通過shader,不過和傳統的shader的不同之處在於,compute shader並非傳統的渲染流水線中的一個階段,相反它主要用來計算原本由CPU處理的通用計算任務,這些通用計算常常與圖形處理沒有任何關係,因此這種方式也被稱為GPGPU——General-purpose computing on graphics processing units,圖形處理器通用計算。

利用這些功能,之前由CPU來實現的計算就可以轉移到計算能力更強大的GPU上來進行了,比如物理計算、AI等等。

而Unity的Compute Shader十分接近DirectCompute,最初Unity引入Compute Shader時僅僅支持DirectX 11,不過目前的版本已經支持別的圖形API了。詳情可以參考:Unity - Manual: Compute shaders。

在Unity中我們可以很方便的創建一個Compute Shader,一個Unity創建的默認Compute Shader如下所示:

利用GPGPU計算大規模群落模擬行為

這裡我先簡單的介紹一下這個Compute Shader中的相關概念,首先在這裡我們指明了這個shader的入口函數。


#pragma kernel CSMain

之後,聲明了在compute shader中操作的數據。

RWTexture2D<float4> Result;

這裡使用的是RWTexture2D,而我們更常用的是RWStructuredBuffer(RW在這裡表示可讀寫)。

之後是很關鍵的一行:


[numthreads(8,8,1)]

這裡首先要說一下Compute Shader執行的線程模型。DirectCompute將並行計算的問題分解成了多個線程組,每個線程組內又包含了多個線程。

利用GPGPU計算大規模群落模擬行為

[numthreads(8,8,1)]的意思是在這個線程組中分配了8x8x1=64個線程,當然我們也可以直接使用


[numthreads(64,1,1)]

因為三維線程模型主要是為了方便某些使用情景,和性能關係不大,硬體在執行時仍然是把所有線程當做一維的。

至此,我們已經在shader中確定了每個線程組內包括幾個線程,但是我們還沒有分配線程組,也沒有開始執行這個shader。

和一般的shader不同,compute shader和圖形無關,因此在使用compute shader時不會涉及到mesh、material這些內容。相反,compute shader的設置和執行要在c#腳本中進行。

利用GPGPU計算大規模群落模擬行為

在c#腳本中準備、傳送數據,分配線程組並執行compute shader,最後數據再從GPU傳遞迴CPU。

不過,這裡有一個問題需要說明。雖然現在將計算轉移到GPU後計算能力已經不再是瓶頸,但是數據的轉移此時變成了首要的限制因素。而且在Dispatch之後直接調用GetData可能會造成CPU的阻塞。因為CPU此時需要等待GPU計算完畢並將數據傳遞迴CPU,所以希望日後Unity能夠提供一個非同步版本的GetData。

最後將行為模擬的邏輯從CPU轉移到GPU之後,模擬10,000個boid組成的大群組在我的筆記本上已經能跑在30FPS上下了。

利用GPGPU計算大規模群落模擬行為

文章摘自博客園


更多IT精品課程,訪問中公優就業官網:http://xue.ujiuye.com

勤工儉學計劃」,給你一個真正0元學習IT技術的機會!

http://www.ujiuye.com/zt/qgjx/?wt.bd=fq37300j

找工作太難?不是你不行,我們來幫你!

http://www.ujiuye.com/zt/jyfc/?wt.bd=fq37300j

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 IT優就業 的精彩文章:

原來,我看的是廣告,順帶插播電視劇而已
COM編程 深入COM框架以及實現簡單的COM
CSS:transition過渡放在偽類中與應用的區別

TAG:IT優就業 |

您可能感興趣

AI 規模化 GPU 計算更上一層!英偉達 HGX-2 伺服器平台正式發布
CAP@NTU 大規模圖計算系統研究進展
微軟為OCP計算項目推出雲SSD存儲新規範
從CPU、GPU到HPC,Xe架構為計算帶來指數級加速
用機器學習構建O(N)複雜度的排序演算法,可在GPU和TPU上加速計算
AMD 突破CPU和GPU極限 領跑高性能計算
用機器學習構建O複雜度的排序演算法,可在GPU和TPU上加速計算
如何利用GPU加速計算過程
英偉達聯手Arm打造高性能計算,用GPU加速器支持Arm CPU
AMD推出首款7nm製程GPU,應用於AI、雲計算等領域
CGDC上海:AMD工程師現場介紹GPU加速與非同步計算
IDC:AI風口,GPU加速計算市場起飛
MODEL 3量產計算失誤 馬斯克展開大規模裁員
NVIDIA 發布了世界上「最大」的 GPU,與一款「小型」計算機
利用ALL和ALLSELECTED靈活計算佔比
GPU 加速數據科學計算
OSPF SPF計算的退避演算法
AI計算行業巨震:英偉達發布全球最大GPU
NVIDIA TITAN V翻車,在科學模擬計算中無法得出可靠結果
新華三亮相GTC CHINA大會,以高效計算力加速AI變革