高性能計(jì)算

我們平時(shí)在做業(yè)務(wù)的時(shí)候很少會(huì)有性能上的瓶頸,偶爾產(chǎn)生的UI層的卡頓也是我們對(duì)程序結(jié)構(gòu)設(shè)計(jì)的不合理產(chǎn)生的。但是性能優(yōu)化卻是一個(gè)好的程序員所應(yīng)具備的兆览,而且在某些特殊的場(chǎng)景下,我們還要有能力去解決很多極限的性能問(wèn)題塞关,這里就來(lái)聊聊高性能計(jì)算方面的問(wèn)題抬探。

首先我們將這類問(wèn)題分為兩種:

  1. 減少計(jì)算量
  2. 加快單位時(shí)間的計(jì)算量

減少計(jì)算量

對(duì)于減少計(jì)算量來(lái)說(shuō),大家都是最熟悉的帆赢,也是平時(shí)碰到的最多的方法小压。

算法優(yōu)化

最常見的要屬算法優(yōu)化,比如查找算法椰于,用二分法代替順序查找怠益,排序用快速排序代替冒泡排序。

另一個(gè)比較典型的例子就是高斯模糊算法瘾婿,將一次二維矩陣的乘法轉(zhuǎn)化為兩次一維矩陣的乘法溉痢,雖然看似改變很小,但是在整個(gè)圖片的計(jì)算量上出入非常的大憋他。以3*3大小的矩陣來(lái)看孩饼,一次二維矩陣乘法需要9次浮點(diǎn)乘法,而兩次一維矩陣僅需要2*3次浮點(diǎn)乘法竹挡,如果是6*6的矩陣镀娶,這個(gè)比例將會(huì)達(dá)到36/12

數(shù)據(jù)結(jié)構(gòu)優(yōu)化

在我們需要更高性能的時(shí)候揪罕,我們不太可能一個(gè)方案能夠滿足所有的情況梯码,往往需要特定的場(chǎng)景使用特定的方案。

在隨機(jī)讀取遠(yuǎn)大于隨機(jī)寫入的時(shí)候好啰,數(shù)組的確是一個(gè)好方案轩娶,但是如果隨機(jī)寫入遠(yuǎn)大于隨機(jī)讀取的時(shí)候,鏈表的性能就會(huì)優(yōu)于數(shù)組框往。如果讀取和寫入都比較頻繁鳄抒,那么樹的結(jié)構(gòu)可能會(huì)是你的首選,根據(jù)所需不同可以采用平衡二叉樹椰弊,B/B+樹许溅,跳躍鏈表等。

如果需要大量寫入磁盤秉版,順序的讀取贤重,比如日志系統(tǒng)這種,那么Google的LevelDB也是一個(gè)非常好的選擇清焕。

總之并蝗,根據(jù)需要來(lái)選擇適合的數(shù)據(jù)結(jié)構(gòu)也能大量的提升性能祭犯。

空間換取時(shí)間

要知道,很多的計(jì)算是重復(fù)的滚停,而這些重復(fù)的計(jì)算可能會(huì)消耗我們大量的時(shí)間沃粗,那么我們?cè)诳臻g充足的情況下,何不緩存這一部分的數(shù)據(jù)的铐刘?

其實(shí)很多的第三方庫(kù)都使用了這種思想的陪每,索引也可以認(rèn)為是這種思想。這里舉個(gè)簡(jiǎn)單的例子镰吵。

在圖片處理的過(guò)程中檩禾,卷積的計(jì)算量是非常大的,而乘法占了很大一部分比例疤祭。而根據(jù)我的了解盼产,ARM在處理乘法的時(shí)候,可能需要6個(gè)時(shí)鐘周期勺馆,而加法只需要一個(gè)戏售,如果能將乘法的結(jié)果緩存下來(lái),通過(guò)加法訪問(wèn)是不是一種可行的方案呢草穆?一個(gè)顏色的色值只有0~255的區(qū)間灌灾,是一個(gè)可以窮舉的范圍,所以緩存這部分結(jié)果悲柱,通過(guò)偏移量(也就是加法)來(lái)訪問(wèn)結(jié)果锋喜,是否也可以減少計(jì)算時(shí)間呢。

這種方法一般都會(huì)有一個(gè)閾值豌鸡,超過(guò)這個(gè)閾值之后才會(huì)有明顯的性能差距嘿般,所以在使用之前需要評(píng)估好自己的場(chǎng)景是否會(huì)處于優(yōu)化的閾值內(nèi)。

低等語(yǔ)言實(shí)現(xiàn)

很多高級(jí)語(yǔ)言在實(shí)現(xiàn)的時(shí)候涯冠,會(huì)附加一部分高級(jí)語(yǔ)言的特性炉奴,比如內(nèi)存回收機(jī)制等,越是底層的語(yǔ)言我們?cè)绞悄軌蚩刂破溆?jì)算量蛇更。

極端的例子就是采用匯編方案瞻赶,這樣能夠最為極限的控制其性能。當(dāng)然這樣的問(wèn)題是兼容性問(wèn)題械荷,需要為多個(gè)平臺(tái)分別寫匯編代碼共耍。其中OpenCV中的部分計(jì)算過(guò)程就是采用了匯編語(yǔ)言實(shí)現(xiàn)的。

這種方案對(duì)于其他高級(jí)語(yǔ)言(JAVA吨瞎,JS等),采用C來(lái)實(shí)現(xiàn)其底層穆咐,或許是個(gè)好的嘗試颤诀。但是使用匯編這種方法雖然有效字旭,但是不太建議,畢竟在晦澀程度和兼容性上考慮崖叫,帶來(lái)的性價(jià)比并不高遗淳,只有在極少數(shù)的特定情況下,才會(huì)考慮心傀。

加快單位時(shí)間的計(jì)算量

除了從計(jì)算量上來(lái)優(yōu)化屈暗,我們還可以通過(guò)一些其他手段,包括更優(yōu)秀的硬件來(lái)幫助我們脂男。

并行計(jì)算

目前的大部分CPU都不是單核的了养叛,包括很多移動(dòng)設(shè)備上的。但是如此高的性能我們往往不能很充分的利用宰翅。

在iOS中就有一個(gè)適合并發(fā)計(jì)算的接口dispatch_apply弃甥。采用多線程可以最大限度的開發(fā)出CPU的潛能。

CPU層面上的浮點(diǎn)計(jì)算

很多場(chǎng)景下汁讼,都是浮點(diǎn)乘法運(yùn)算消耗了大量的時(shí)間淆攻,特別是對(duì)于ARM系列,但是新型的ARM特別設(shè)計(jì)了關(guān)于浮點(diǎn)及向量的優(yōu)化(VFP或者稱NEON)嘿架。

在iOS中瓶珊,vImage就是利用了這一特性進(jìn)行了優(yōu)化,如果有少量的圖片運(yùn)算可以使用vImage來(lái)加快我們的速度耸彪。

ARM流水線優(yōu)化

ARM系列的CPU一般都有采用流水線的架構(gòu)伞芹,因?yàn)槊恳粭l指令的執(zhí)行都需要經(jīng)過(guò)取址-譯碼-執(zhí)行這幾個(gè)步驟,采用流水線架構(gòu)可以增加執(zhí)行效率搜囱。

但是這也有一個(gè)反例丑瞧,就是在B相關(guān)跳轉(zhuǎn)指令的時(shí)候,需要清空流水線蜀肘,重新加載绊汹,這也會(huì)帶來(lái)一定的性能損耗。

也就是說(shuō):

int i = 0; x += i; 
i++; x += i;
i++; x += i;
i++; x += i;
i++; x += i;
i++; x += i;
i++; x += i;
i++; x += i;
i++; x += i;
i++; x += i;
i++; x += i;

for (int i = 0; i <= 10; i++) x += i;

效率要高很多扮宠。當(dāng)然這里有點(diǎn)吹毛求疵了西乖,一般情況下我們還是不需要考慮這部分內(nèi)容的。

GPU

其實(shí)目前來(lái)說(shuō)坛增,影響最大的莫過(guò)于圖像的處理获雕,普通的業(yè)務(wù)慢一點(diǎn)和快一點(diǎn)其實(shí)很難分辨出來(lái),也沒(méi)有必要去如此極限的優(yōu)化收捣,而圖像的計(jì)算量之龐大届案,很容易就可以感覺(jué)出來(lái),同時(shí)圖像處理速度還制約著視頻的幀率問(wèn)題罢艾,所以問(wèn)題的嚴(yán)重程度要高很多楣颠。

那么說(shuō)到圖像處理尽纽,就不得不涉及到GPU了。目前移動(dòng)端基本都支持OpenGL2.0或OpenGL3.0童漩,所以如果要跨平臺(tái)使用可以考慮OpenGL來(lái)優(yōu)化弄贿。但是如果只考慮iOS平臺(tái),讓我們來(lái)看看iOS平臺(tái)有哪些特定的利用GPU進(jìn)行優(yōu)化的方案矫膨。

GPUImage

這是一個(gè)利用OpenGL的開源庫(kù)差凹,是一個(gè)跨平臺(tái)的第三方庫(kù),里面封裝了很多濾鏡侧馅,同時(shí)也支持圖片危尿、視頻的處理,對(duì)于自定義和擴(kuò)展也比較方便施禾,是一款非常好用的開源庫(kù)脚线。

CIContext

Core Image是蘋果官方提供的一款圖像處理庫(kù),里面包含了眾多的濾鏡弥搞。其中CIContext可以指定為glContext邮绿,就是GPU環(huán)境了。一般來(lái)說(shuō)攀例,我們平時(shí)開發(fā)使用船逮,CIImage已經(jīng)足夠了。

CImage的擴(kuò)展也非常方便粤铭,有一種類似于openGL的GLSL的語(yǔ)言挖胃,KLSL。有興趣的人可以自己去研究研究梆惯。

Metal

Metal是蘋果比較新的一個(gè)庫(kù)酱鸭,專門為了替代OpenGL而做的,降低了OpenGL的學(xué)習(xí)成本垛吗。

據(jù)官方稱凹髓,加入了眾多的優(yōu)化。其中一個(gè)比較明顯的就是怯屉,將shader的編譯過(guò)程放到了編譯期蔚舀,而不是運(yùn)行期,也就是說(shuō)锨络,比起OpenGL赌躺,少了一步glCompileShader

同時(shí)Metal也和iOS的特性結(jié)合的比較好羡儿,使用起來(lái)也比OpenGL簡(jiǎn)單很多礼患。當(dāng)然這些都是iOS平臺(tái)的特性,不支持跨平臺(tái)。

OpenCL

這個(gè)是對(duì)應(yīng)于mac系統(tǒng)的讶泰,其他系統(tǒng)上也有實(shí)現(xiàn)咏瑟,目前還不支持移動(dòng)端拂到。

多緩沖FrameBuffer的GPU

對(duì)于視頻這類連續(xù)的計(jì)算痪署,以上的方案已經(jīng)非常的優(yōu)秀了,但是我們還是沒(méi)有榨干機(jī)器的性能兄旬。:D

1.png

一張圖片的處理流程可以表示為上圖狼犯,CPU需要將數(shù)據(jù)參數(shù)準(zhǔn)備好,然后拷貝到GPU內(nèi)存空間领铐,然后等待GPU執(zhí)行悯森。GPU執(zhí)行完之后,需要等待CPU準(zhǔn)備好下一張圖片的數(shù)據(jù)并拷貝到GPU空間,在這之間是留了很多的空白時(shí)間的。

我們知道OpenGL并不是線程安全的由驹,也就是說(shuō)GPU空間是可以多線程同時(shí)訪問(wèn)的姿染,那么我們可以通過(guò)多個(gè)緩沖區(qū)來(lái)解決上述空白時(shí)間的問(wèn)題。

2.png

上圖就是我們想要達(dá)到的效果箍土,而下圖是我們采用3個(gè)緩沖區(qū),實(shí)際上的效果。

3.png

最后

以上是對(duì)高性能計(jì)算幾種方式的一個(gè)簡(jiǎn)單概括褥傍,具體的情況需要根據(jù)自己的實(shí)際情況來(lái)選擇。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末喇聊,一起剝皮案震驚了整個(gè)濱河市恍风,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌誓篱,老刑警劉巖朋贬,帶你破解...
    沈念sama閱讀 212,816評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異窜骄,居然都是意外死亡锦募,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門啊研,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)御滩,“玉大人,你說(shuō)我怎么就攤上這事党远∠鹘猓” “怎么了?”我有些...
    開封第一講書人閱讀 158,300評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵沟娱,是天一觀的道長(zhǎng)氛驮。 經(jīng)常有香客問(wèn)我,道長(zhǎng)济似,這世上最難降的妖魔是什么矫废? 我笑而不...
    開封第一講書人閱讀 56,780評(píng)論 1 285
  • 正文 為了忘掉前任盏缤,我火速辦了婚禮,結(jié)果婚禮上蓖扑,老公的妹妹穿的比我還像新娘唉铜。我一直安慰自己,他們只是感情好律杠,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,890評(píng)論 6 385
  • 文/花漫 我一把揭開白布潭流。 她就那樣靜靜地躺著,像睡著了一般柜去。 火紅的嫁衣襯著肌膚如雪灰嫉。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,084評(píng)論 1 291
  • 那天嗓奢,我揣著相機(jī)與錄音讼撒,去河邊找鬼。 笑死股耽,一個(gè)胖子當(dāng)著我的面吹牛根盒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播豺谈,決...
    沈念sama閱讀 39,151評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼郑象,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了茬末?” 一聲冷哼從身側(cè)響起厂榛,我...
    開封第一講書人閱讀 37,912評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎丽惭,沒(méi)想到半個(gè)月后击奶,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,355評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡责掏,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,666評(píng)論 2 327
  • 正文 我和宋清朗相戀三年柜砾,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片换衬。...
    茶點(diǎn)故事閱讀 38,809評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡痰驱,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出瞳浦,到底是詐尸還是另有隱情担映,我是刑警寧澤,帶...
    沈念sama閱讀 34,504評(píng)論 4 334
  • 正文 年R本政府宣布叫潦,位于F島的核電站蝇完,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜短蜕,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,150評(píng)論 3 317
  • 文/蒙蒙 一氢架、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧朋魔,春花似錦岖研、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至解滓,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間筝家,已是汗流浹背洼裤。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留溪王,地道東北人腮鞍。 一個(gè)月前我還...
    沈念sama閱讀 46,628評(píng)論 2 362
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像莹菱,于是被迫代替她去往敵國(guó)和親移国。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,724評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容