GPU(Graphics Processing Unit)减拭,也即顯卡蔽豺,是一種專門在個人電腦、工作站拧粪、游戲機(jī)和一些移動設(shè)備(如平板電腦修陡、智能手機(jī)等)上作圖像運(yùn)算工作的微處理器沧侥。它已經(jīng)是個人PC和移動設(shè)備上不可或缺的芯片,有界面有顯示的地方濒析,一般就離不開它正什。高清電視、智能手機(jī)号杏、個人電腦婴氮。
GPU的產(chǎn)生是為了解決圖形渲染效率的問題,但隨著技術(shù)進(jìn)步盾致,GPU越來越強(qiáng)大主经,尤其是shader出現(xiàn)之后(這個允許我們在GPU上編程),GPU能做的事越來越多庭惜,不再局限于圖形領(lǐng)域罩驻,也就有人動手將其能力擴(kuò)展到其他計算密集的領(lǐng)域,這就是GP(General Purpose)GPU护赊。
考慮到當(dāng)下惠遏,圖形領(lǐng)域的技術(shù)人員對GPU已經(jīng)是很熟悉了,其他那些關(guān)心GPU的骏啰,無非是向往GPU的強(qiáng)大并行運(yùn)算能力节吮,想利用它做通用計算的,因此判耕,本文會特別提GPGPU透绩。
?第一行為圖形引擎/算法庫,
第二行為圖形標(biāo)準(zhǔn)
第三行為不同型號的GPU
開發(fā)者直接調(diào)用驅(qū)動接口是很不方便且不安全的壁熄,為此帚豪,需要有一套給上游應(yīng)用開發(fā)提供的API,?開發(fā)者使用這組API草丧,去觸發(fā)GPU的功能狸臣,這一套API就是圖形標(biāo)準(zhǔn)。
如圖所示:
作為開發(fā)者昌执,自然非常希望這套API是統(tǒng)一的固棚,不過很不幸,由于?歷史原因仙蚜、性能問題及永恒的利益之爭,統(tǒng)一似乎是不可能的事情厂汗。還好委粉,主流的標(biāo)準(zhǔn)就那么幾個,而且編程原理基本上一樣娶桦,代碼封一層去適應(yīng)下贾节,一般也就可以了汁汗。
個人PC一般是Windows系統(tǒng),主要使用Direct3D栗涂,一般也支持OpenGL知牌。
服務(wù)器、mac等一般是類unix系統(tǒng)(Ubuntu斤程、Redit角寸、macOS),支持開放標(biāo)準(zhǔn)OpenGL忿墅。
智能手機(jī)扁藕、機(jī)頂盒等嵌入式設(shè)備一般是類unix系統(tǒng)(iOS、Android疚脐、阿里云等)亿柑,支持開放標(biāo)準(zhǔn)OpenGLES(OpenGL標(biāo)準(zhǔn)作裁剪而得),不過蘋果覺得OpenGL效率太低棍弄,不能充分發(fā)揮自家GPU的優(yōu)勢望薄,就搞了一個metal。后面 AMD 也這么認(rèn)為呼畸,搞了一個mantle痕支,到了最后khronos組織也一致這么認(rèn)為了,就推出了vulkan役耕。
Direct3D只適用于Windows采转,metal只適用于ios,mantle只適用于AMD的GPU瞬痘,OpenGL/OpenGL ES及新推出的vulkan是通用開放標(biāo)準(zhǔn)故慈,它們由khronos組織維護(hù),理論上適用于任何操作系統(tǒng)框全,但需要GPU廠商去支持察绷。
最早的圖形標(biāo)準(zhǔn)是聯(lián)合組織維護(hù)的OpenGL,后面微軟覺得這個組織效率太低津辩,于是結(jié)合自己的系統(tǒng)弄了Direct3D拆撼,在后續(xù)的較量中漸漸取得了絕對優(yōu)勢(率先推出shader是競爭拐點(diǎn))。OpenGL在PC端漸漸不行的時候喘沿,蘋果的iphone及一系列Android機(jī)又在移動端拯救了它(開放的好處闸度,移動端只能用OpenGL)。但OpenGL這套標(biāo)準(zhǔn)實在是有硬傷蚜印,人們雖然將就著用莺禁,并且不斷升級改良,也實在到了需要進(jìn)一步突破的時候窄赋,于是就有了 vulkan哟冬。
如這篇文章所述:
http://blog.csdn.net/mythma/article/details/50808817
vulkan在設(shè)計上無疑是先進(jìn)的楼熄,一是廢棄了OpenGL的線程上下文及狀態(tài)機(jī)模式(這導(dǎo)致圖形引擎在考慮多線程并發(fā)時的設(shè)計超痛苦,且很容易出Bug)浩峡,二是廢棄了shader前端可岂、只支持一種叫SPIR-V的shader中間碼(一方面防止奇葩低端gpu在編譯shader時報語法錯誤,另一方面翰灾,可以對shader代碼作一定的產(chǎn)權(quán)保護(hù))缕粹。不過,引擎開發(fā)者预侯、?驅(qū)動開發(fā)者及系統(tǒng)維護(hù)者適應(yīng)這一變更致开,需要一段時間。
目前的通用計算標(biāo)準(zhǔn)主要是OpenCL萎馅,最新版到2.1双戳,但人們用得最多的是NVIDIA的專屬API:CUDA。
Google 一直在Android系統(tǒng)中強(qiáng)推 RenderScript糜芳,不在系統(tǒng)層面支持OpenCL飒货,很大程度上限制了移動端的通用計算應(yīng)用。
這篇文章分析 OpenCL和RenderScript 得比較好:
http://blog.csdn.net/zhuanshenweiliu/article/details/40746873
在個人PC峭竣、游戲主機(jī)及服務(wù)器市場塘辅,主要是NVIDIA和AMD兩強(qiáng)爭霸,?傳統(tǒng)的圖形渲染上皆撩,不分伯仲扣墩;通用計算方面,由于NVIDIA先行了一步扛吞,推出CUDA呻惕,生態(tài)圈已成,?擁有絕對優(yōu)勢滥比;不妨看今年據(jù)說要爆發(fā)的VR(虛擬現(xiàn)實)上亚脆,兩邊的成績?nèi)绾巍?/p>
嵌入式設(shè)備市場上,GPU品種要繁多一些盲泛,論第一還是首推iphone所采用的powerVR(Imagination公司所產(chǎn))濒持,其次是高通的Adreno系列(如小米、三星S7)寺滚,繼而Arm的mali系列(海思自用圖芯吃虧之后柑营,改用mali系列,圖形能力?脫胎換骨【但還是相對弱勢】村视,不過P6官套、D2給消費(fèi)者留下的圖形能力不行的陰影至今仍在)。其他份額較少的gpu就不羅列了。
談到硬件虏杰,不妨提一下相應(yīng)的驅(qū)動框架:
參考文章
http://blog.csdn.net/myarrow/article/details/17375483
(這一部分建議沒有背景知識的先跳過)
一般來說,gpu的驅(qū)動框架類似下圖:
1勒虾、窗口標(biāo)準(zhǔn)的實現(xiàn)是與操作系統(tǒng)強(qiáng)相關(guān)的纺阔,它為圖形渲染提供目標(biāo)內(nèi)存。一般來說修然,只要支持的標(biāo)準(zhǔn)不變笛钝,操作系統(tǒng)更換/升級,對驅(qū)動的代碼影響就只限在窗口這一塊愕宋。
2玻靡、編譯器用于編譯shader或kernel,編譯kernel需要用llvm預(yù)編譯中贝,編譯器會大一些囤捻。低端GPU的編譯器特別容易出現(xiàn)各種語法不支持,讓寫shader的人痛苦萬分邻寿。
3蝎土、通用計算的實現(xiàn)就是把kernel編譯后轉(zhuǎn)成任務(wù)扔給內(nèi)核去跑,相對簡單绣否。
4誊涯、圖形渲染的實現(xiàn)則需要考慮到一幀中可能有重復(fù)渲染/過度繪制的情況,為了這方面做優(yōu)化蒜撮,一幀中的任務(wù)有必要做一下組織暴构,因此要有個幀管理器模塊。
5段磨、內(nèi)存管理用于管理顯存取逾,但顯存不一定是在GPU芯片上(獨(dú)顯和集顯的區(qū)別)。
6薇溃、不管上層玩得多么風(fēng)生水起菌赖,到了內(nèi)核都是一個個的任務(wù),內(nèi)核模塊執(zhí)行沐序、調(diào)度便是琉用。
一般而言,應(yīng)用開發(fā)者不會直接去調(diào)用圖形標(biāo)準(zhǔn)API策幼,而是使用圖形引擎/算法庫邑时。原因如下:
1、圖形標(biāo)準(zhǔn)API非常繁瑣難用特姐,需要習(xí)慣GPU編程的思想晶丘,有必要做適度封裝,減輕上層應(yīng)用的開發(fā)難度。
2浅浮、如上文所述沫浆,圖形標(biāo)準(zhǔn)有多種,且不同硬件對同一標(biāo)準(zhǔn)的支持情況也不一定相同滚秩,有必要做一個中間層专执,專門去處理這些問題。
3郁油、一些圖形圖像算法需要較強(qiáng)的專業(yè)知識本股,得用專業(yè)人才去編寫。
應(yīng)用開發(fā)者開發(fā)界面時桐腌,主要是用操作系統(tǒng)提供的View框架拄显。為支持這個框架,操作系統(tǒng)都會實現(xiàn)一套2D引擎案站,開發(fā)者?間接使用了圖形引擎躬审。
如這個應(yīng)用間接使用了Android的hwui引擎:
要求界面炫酷的應(yīng)用,典型如游戲嚼吞,會去用一些3D引擎盒件。目前手游上主流的游戲引擎是Unity3D和cocos2D,unity3D免費(fèi)但不開源舱禽,cocos2D是做了捕魚達(dá)人游戲的公司公布并開源的炒刁。PC游戲方面,以收費(fèi)商業(yè)引擎為主誊稚,且一般是基于D3D(這就是為什么Linux翔始、類linux?系統(tǒng)下游戲那么少),典型如虛幻引擎里伯,特效強(qiáng)大城瞎。ogre是主要用于PC的久負(fù)盛名的開源引擎,支持OpenGL疾瓮,完美時空基于ogre做過游戲脖镀。
網(wǎng)易的天下HD用的unity3D(沒記錯的話。狼电。蜒灰。)
虛幻引擎做的某款游戲:
圖形引擎多種多樣,這里僅僅是列了很少一部分肩碟,畢竟是個大坑强窖,只能簡單提一下。
通用計算引擎所見的主要是 ArrayFire削祈,主頁:http://arrayfire.com/翅溺。它提供了一系列用OpenCL/Cuda加速的算法庫脑漫,并提供方便的接口去開發(fā)GPU加速的算法。
caffe是工業(yè)上最常用的深度學(xué)習(xí)框架咙崎,支持多臺裝配NVIDIA的服務(wù)器同時進(jìn)行深度學(xué)習(xí)优幸。
OpenCV是一個龐大的圖像算法庫,cl-opencv對其核心算法基于OpenCL作了加速褪猛。
PG-Storm 則據(jù)說是用 GPU加速的 postsql劈伴,具體沒看過,SQL查詢中的變長字符串處理是GPU優(yōu)化的難點(diǎn)握爷,以前看過的demo都回避了這一問題,不知道這個是否解決了严里。
拋開具體的硬件新啼,標(biāo)準(zhǔn),以及引擎來說刹碾,GPU?本身代表著和CPU不一樣的編程思想:CPU好比幾個高智商精英燥撞,什么都能做且做得快;而GPU就是一大群低學(xué)歷農(nóng)民工迷帜,每個人可以做的有限物舒,也不快,但人數(shù)優(yōu)勢決定其整體速度完爆精英們戏锹。
GPU編程冠胯,就像指揮一大群螞蟻,有幾個通用原則:
1锦针、讓螞蟻們做的工作量盡可能相等荠察,因為你要等所有螞蟻都完成才能進(jìn)行下一步。
2奈搜、不要在意每一只螞蟻的工作細(xì)節(jié)悉盆,請關(guān)注你給螞蟻準(zhǔn)備的糧食。(GPU編程的主要工作是配置參數(shù))
3馋吗、螞蟻們所在的世界和你的世界有矩離焕盟,你要教導(dǎo)它們做事(提供shader或kernel),向它們喊話(觸發(fā)執(zhí)行API)宏粤,并提供做事的資源(內(nèi)存數(shù)據(jù)傳到顯存)脚翘。
管線是GPU上做圖形渲染編程最為重要的概念,GPU就像一個炒菜機(jī)商架,程序員要做的主要事情是給它配原料堰怨,至于翻滾、加熱等工序蛇摸,不在程序員的控制之內(nèi)备图。
參考:
http://www.360doc.com/content/13/0107/18/9934052_258805453.shtml
簡單的記法:
頂點(diǎn)——圖元——光柵化——著色
圖形渲染的基本思想就是先定形,再定色,
下圖是OpenGL ES 編程流程:
使用GPU加速算法揽涮,務(wù)必做到批量化處理抠藕,只處理1條或1行數(shù)據(jù),調(diào)用GPU接口的交互時間會遠(yuǎn)遠(yuǎn)超出計算時間蒋困。
這里的交流盾似,一方面指的是CPU與GPU之間的數(shù)據(jù)傳輸,另一方面指?調(diào)觸發(fā)運(yùn)算的API雪标。
從事SOC開發(fā)的工作時零院,對此做了許多嘗試均告失敗。移動端的通用GPU計算實在是?很難有進(jìn)展的一件事情村刨,首先告抄,受限于可憐的GPU性能及弱爆了的內(nèi)存?zhèn)鬏攷挘珿PU加速往往被多線程+neon完爆嵌牺;其次打洼,移動端作密集運(yùn)算的場景著實有限,最需要運(yùn)算的也就相機(jī)模塊與圖像編解碼逆粹,但?這么有限的場景廠商完全可以上DSP/ISP募疮,GPU在這時并沒太大優(yōu)勢。目前而言僻弹,在移動端做優(yōu)化阿浓,主要還是運(yùn)用OpenGL和neon。
然而隨著普適計算蹋绽、情景智能搔扁、圖像識別的發(fā)展,移動端的通用計算將會變得越來越?有意義蟋字,更快更?準(zhǔn)確的機(jī)器學(xué)習(xí)算法的使用稿蹲,可以讓手機(jī)更智能。
目前的分布式計算框架鹊奖,通用型的如Hadoop苛聘、Spark、flink等都是只能利用CPU的(雖然也可以用GPU忠聚,但用起來很麻煩且兼容性不好)设哗。
用上了 GPU 的,主要是特定設(shè)備上跑固定算法(Deep Learning)两蟀,不具備通用性网梢。以致于幾乎Tesla就是DL的代表,
http://server.yesky.com/es/355/50639355.shtml
若有一個通用的分布式異構(gòu)計算框架赂毯,可以大幅降低機(jī)器學(xué)習(xí)战虏、圖像處理拣宰、視頻制作等計算密集業(yè)務(wù)在時間和機(jī)器上的消耗,其價值是非常大的烦感。
此外巡社,基于此可以設(shè)計分布式GPU數(shù)據(jù)庫,大大提升查詢的性能手趣。