【轉(zhuǎn)載】Matlab代碼的耗時(shí)分析、優(yōu)化晌端、加速

轉(zhuǎn)自 http://blog.sina.com.cn/s/blog_6f64146b01019ojm.html

Profile(分析)

在加速你的matlab程序之前捅暴,你需要知道你的代碼哪一部分運(yùn)行最慢。matlab提供個(gè)簡(jiǎn)單的機(jī)制咧纠,讓你能夠知道你的代碼的某一部分運(yùn)行所占用CPU時(shí)間蓬痒。通過(guò)在代碼段開(kāi)始添加tic,及在結(jié)束添加toc漆羔;matlab就能計(jì)算出這一代碼段的運(yùn)行時(shí)間梧奢。
Tic和toc方法存在兩個(gè)問(wèn)題:

(1)顯示的時(shí)間是運(yùn)行時(shí)間“wall clock”狱掂。這個(gè)時(shí)間受你在運(yùn)行你的代碼時(shí),你的計(jì)算機(jī)是否同時(shí)運(yùn)行其它別的程序亲轨。

(2)你需要不斷地壓縮計(jì)時(shí)范圍來(lái)查找你代碼運(yùn)行最慢的位置趋惨。

一個(gè)最好的方法是利用matlab 內(nèi)嵌的代碼分析器。在你的程序前面通過(guò)添加命令profile on;及在程序結(jié)束添加profile viewer;并運(yùn)行你的程序惦蚊。當(dāng)程序正常運(yùn)行結(jié)束時(shí)器虾,代碼分析器窗口將彈出,并顯示分析結(jié)果蹦锋。它包含的信息
有:

Function Name :函數(shù)名兆沙;

Calls :函數(shù)被調(diào)用次數(shù);

Total Time :執(zhí)行該函數(shù)的CPU總用時(shí)莉掂,包含任何其它被它調(diào)用的函數(shù)的CPU時(shí)間葛圃。

Self Time :執(zhí)行該函數(shù)的CUP總用時(shí),不包含任何其它被它調(diào)用的函數(shù)的CUP時(shí)間憎妙。

Total Time Plot :時(shí)間用時(shí)的曲線(xiàn)圖装悲。

以上信息可進(jìn)行各種排序和詳細(xì)查看。

注意:當(dāng)你完成你的代碼分析后尚氛,請(qǐng)刪除profile on和profile viewer诀诊,因?yàn)榍度氪a分析器會(huì)使用的程序運(yùn)行變慢。

標(biāo)準(zhǔn)提示

有問(wèn)題找?guī)椭臋n阅嘶。學(xué)會(huì)使用幫助文檔属瓣,學(xué)會(huì)針對(duì)待解決的問(wèn)題檢索文檔資料。

☆性能

查看MATLAB->Programming->Improving Performace and Memory Usage;或MATLAB->Programming

Fundamentals->Performace->Techniques for Improveing Performace讯柔。

多線(xiàn)程

如果你使用的是多核心的計(jì)算機(jī)抡蛙,那么你就可以讓Matlab同時(shí)運(yùn)行多個(gè)線(xiàn)程,Matlab程序中一些底層的函數(shù)

(Low-level function)就有可能采用并行計(jì)算的方法魂迄。打開(kāi)多線(xiàn)程的方法:File->Preferences選擇General->

Multithreading粗截。扣選Enable multihread computation box捣炬。如果不限制使用核心的數(shù)目熊昌,可以保留使用Automatic。

注意:Matlab R2008a之前的版本在AMD處理器上是不支持多線(xiàn)程的湿酸。

向量化循環(huán)

Matlab的運(yùn)算是針對(duì)向量(矢量)和矩陣進(jìn)行設(shè)計(jì)的婿屹,因此它在向量和矩陣上的運(yùn)算速度比采用循環(huán)的方式更快。

例如:

index=0;

for time=0:0.001:60;

index=index+1;

waveForm(index)=cos(time);

end;

采用以下代碼可加快速度推溃。

Time=0:0.01:60;

waveForm=cos(time);

一些有用的昂利,可用于代替循環(huán)的函數(shù):

any();size();find();cumsum();sum();

向量預(yù)分配

Matlab采用內(nèi)存中一塊連續(xù)的空間來(lái)存儲(chǔ)向量和矩陣數(shù)據(jù),而不是用鏈表。這就意味著你每給向量或矩陣增加一元

素蜂奸,Matlab需要尋找一塊足夠大的內(nèi)存區(qū)域來(lái)存儲(chǔ)這個(gè)擴(kuò)大后的向量或矩陣犁苏,然后復(fù)制現(xiàn)有的數(shù)據(jù)到新的內(nèi)存區(qū)

域。在循環(huán)中增加向量或矩陣元素的元數(shù)是允許的扩所,但并不是明智之舉围详,而應(yīng)該是一次性分配向量或矩陣的大小,

或一次性重定義尺寸碌奉。

Results=0;

for index=2:1000;

results(index)=results(index-1)+index;

end

上述代碼將比以下代碼速度慢:

results=zeros(1,1000);

for index=2:1000;

results(kindex)=results(kindex-1)+index;

end;

注意:當(dāng)你需要用zeros()來(lái)創(chuàng)建一個(gè)指定數(shù)據(jù)類(lèi)型的向量或矩陣時(shí)短曾,你可以使用創(chuàng)建參數(shù)來(lái)指定類(lèi)型寒砖,而不是“重鑄”赐劣。results=int8(zeros(1,1000));將創(chuàng)建一個(gè)有1000個(gè)元素的double型零向量,然后把它轉(zhuǎn)換成int8類(lèi)型哩都。如果我們使用results=zeros(1,1000,'int8'); Matlab將支持建立1000個(gè)int8類(lèi)型的向量魁兼,在創(chuàng)建可實(shí)現(xiàn)性及速度上將更具有優(yōu)勢(shì)。

不要改變數(shù)據(jù)類(lèi)型

Matlab為了能夠支持寬松的數(shù)據(jù)類(lèi)型(例如一個(gè)變量能夠存儲(chǔ)不同類(lèi)型的數(shù)據(jù)漠嵌,而不是指定它為特定的數(shù)據(jù)類(lèi)型)咐汞,則Matlab除了存儲(chǔ)單純的數(shù)據(jù)之外,還需要伴隨數(shù)據(jù)存儲(chǔ)一定數(shù)量的頭信息(header)儒鹿,這就意味著需要內(nèi)存空間支存儲(chǔ)數(shù)據(jù)類(lèi)型化撕,同時(shí)意味需要在數(shù)據(jù)類(lèi)型轉(zhuǎn)換上支付額外的計(jì)算機(jī)資源開(kāi)支。

對(duì)于實(shí)數(shù)據(jù)使用 real...函數(shù)约炎。

Matlab中的一些函數(shù)能夠同時(shí)適用于實(shí)類(lèi)型數(shù)據(jù)和復(fù)類(lèi)型數(shù)據(jù)植阴。如果你只使用實(shí)數(shù)據(jù),那么采用特定的版本的圾浅,非復(fù)數(shù)據(jù)函數(shù)掠手,那么它運(yùn)行的速度將變得更快。這些函數(shù)如:reallog(), realpow(),realsqrt()狸捕。

使用“短路”邏輯操作

Matlab的“短路”邏輯操作可以在判斷條件達(dá)到充分條件后就停止計(jì)算處理喷鸽,而不需要知道判斷所有條件。例如:if(index>=3)&&(data(index)==5); 當(dāng)index小于3時(shí)灸拍,第二個(gè)條件判斷將不被處理做祝,這樣就少了去判斷data(index)==5)的時(shí)間,提高速度鸡岗。

使用函數(shù)指針

Matlab的一些函數(shù)使用函數(shù)名作用參數(shù)剖淀,常用一個(gè)變量支保存這個(gè)函數(shù)名字符串()如:func='tan';然后用這個(gè)變量作為函數(shù)的參數(shù):fzero(func,0))。這種方法對(duì)于簡(jiǎn)單的函數(shù)調(diào)用是很好的纤房,但是對(duì)于在循環(huán)中的重復(fù)調(diào)用就存在兩個(gè)問(wèn)題:

(1)在每一個(gè)循環(huán)中纵隔,Matlab需要去搜索這個(gè)函數(shù)的路徑(如tan),這需要花費(fèi)時(shí)間。

(2)在循環(huán)過(guò)程中捌刮,路徑可能會(huì)改變碰煌。這會(huì)保證在這一次循環(huán)中,某個(gè)版本的函數(shù)(如tan)被首先調(diào)用绅作,而下一次

循環(huán)中這個(gè)版本的函數(shù)又被首先調(diào)用芦圾,最終會(huì)造成結(jié)果不一致。

解決的辦法是使用文件指針(;或func=@sin),它能返回函數(shù)唯一的識(shí)別碼俄认。調(diào)用方式同上个少。

文件IO

通常高級(jí)輸入輸出操作(load()和save())比一般的低級(jí)操作(fread()和fwrite())快。

☆內(nèi)存使用

關(guān)于內(nèi)存的使用可查看幫助文檔Using Menory Efficently眯杏∫菇梗可查與Memory Usage相關(guān)的信息。

一定記注:可以使用whos()來(lái)查看數(shù)據(jù)變量占有用的內(nèi)存空間大小岂贩。

復(fù)制數(shù)組

當(dāng)你復(fù)制一個(gè)數(shù)組時(shí)茫经,Matlab開(kāi)始只復(fù)制一個(gè)指向數(shù)據(jù)的一個(gè)指針,僅當(dāng)你隨后對(duì)任一版本進(jìn)行修時(shí)萎津,數(shù)據(jù)的復(fù)制

才真正的執(zhí)行卸伞。這種操作包括數(shù)組作為函數(shù)參數(shù)進(jìn)行傳遞的情況-作為值傳遞的參數(shù)傳遞,而不是作為參考的傳

遞锉屈。因此荤傲,你應(yīng)該盡量避開(kāi)對(duì)大數(shù)組進(jìn)行小改動(dòng)的操作。

數(shù)據(jù)不用時(shí)颈渊,釋放內(nèi)存

如果一個(gè)變量以后已經(jīng)不再使用遂黍,那么你可以刪除它c(diǎn)lear VariableName;則這個(gè)小塊的數(shù)據(jù)將可以重用。

注意:如果各變量在內(nèi)存是連續(xù)的儡炼,則Matlab很容易重用這些大塊的內(nèi)存妓湘,因此最好是先建立大的變量,后再建立

小的變量乌询,并且把它們組合起來(lái)榜贴。

結(jié)構(gòu)體存儲(chǔ)

上文已經(jīng)提到,在Matlab中的變量包含有描述數(shù)據(jù)類(lèi)型的頭信息妹田。對(duì)于一個(gè)結(jié)構(gòu)體唬党,則有一個(gè)描述整個(gè)結(jié)構(gòu)的頭信

息,及每個(gè)元素也分別有一個(gè)頭信息鬼佣。為了最小化地使用內(nèi)存驶拱,我們應(yīng)該小心地使用混合數(shù)據(jù)類(lèi)型的數(shù)組和結(jié)構(gòu)。

例如:

pixel.red(1:600,1:400)

pixel.grn(1:600,1:400)

pixel.blu(1:600,1:400)

則我們就需要存儲(chǔ)4個(gè)頭信息晶衷。而:

pixel(1:600,1:400).red

pixel(1:600,1:400).grn

pixel(1:600,1:400).blu

我們就有720001個(gè)頭信息蓝纲。

使用最小的合適的數(shù)據(jù)類(lèi)型

為了減小內(nèi)存使用量阴孟,對(duì)于特定的運(yùn)算經(jīng)常使用最小的數(shù)據(jù)類(lèi)型。例如:

(1)對(duì)于虛部為零的數(shù)據(jù)税迷,最好不要用complex去存儲(chǔ)永丝。

(2)如果精度足夠,可采用single變量箭养,而不用double慕嚷。

(3)使用uint16來(lái)進(jìn)行計(jì)數(shù)操作,它能存儲(chǔ)值為0到65535毕泌。但它比默認(rèn)的double型省一半的內(nèi)存喝检。

使用稀疏矩陣

如果矩陣絕大多的數(shù)據(jù)為零值,可以把它轉(zhuǎn)化成稀疏形式(使用sparse()函數(shù))撼泛。它將只存儲(chǔ)非零數(shù)據(jù)的數(shù)值和索

引挠说。因?yàn)樾枰~外的存儲(chǔ)數(shù)據(jù)的索引,因此只有二維數(shù)據(jù)的零值大約超過(guò)75%時(shí)坎弯,這種方法才是有效的纺涤,否則稀

疏形式反而需要更多的內(nèi)存空間译暂。

☆并行循環(huán)

如果從一個(gè)for循環(huán)的外部看抠忘,for循環(huán)滿(mǎn)足以下標(biāo)準(zhǔn):

(1)循環(huán)的計(jì)數(shù)是整數(shù);

(2)每次循環(huán)都是獨(dú)立的外永;

(3)計(jì)算循環(huán)先后順序無(wú)關(guān)崎脉。

那么這個(gè)for循環(huán)就有可能可以替換成parfor循環(huán)(matlab2008a中可用優(yōu)化算打開(kāi)并行通信池:parfor循環(huán)包含于

matlabpool open 和matlabpool close之間)。

注意:打開(kāi)一個(gè)并行工作池worker pool大約需要10-15秒鐘伯顶,關(guān)閉一個(gè)工作池大概需要5秒鐘囚灼。計(jì)算這個(gè)時(shí)間在

內(nèi),這個(gè)方法對(duì)于循環(huán)時(shí)間超過(guò)30秒的情況才是值得的祭衩。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末灶体,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子掐暮,更是在濱河造成了極大的恐慌蝎抽,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,080評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件路克,死亡現(xiàn)場(chǎng)離奇詭異樟结,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)精算,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,422評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)瓢宦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人灰羽,你說(shuō)我怎么就攤上這事驮履∮阏蓿” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,630評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵玫镐,是天一觀的道長(zhǎng)座每。 經(jīng)常有香客問(wèn)我,道長(zhǎng)摘悴,這世上最難降的妖魔是什么峭梳? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,554評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮蹂喻,結(jié)果婚禮上葱椭,老公的妹妹穿的比我還像新娘。我一直安慰自己口四,他們只是感情好孵运,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,662評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著蔓彩,像睡著了一般治笨。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上赤嚼,一...
    開(kāi)封第一講書(shū)人閱讀 49,856評(píng)論 1 290
  • 那天旷赖,我揣著相機(jī)與錄音,去河邊找鬼更卒。 笑死等孵,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蹂空。 我是一名探鬼主播俯萌,決...
    沈念sama閱讀 39,014評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼上枕!你這毒婦竟也來(lái)了咐熙?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,752評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤辨萍,失蹤者是張志新(化名)和其女友劉穎棋恼,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體分瘦,經(jīng)...
    沈念sama閱讀 44,212評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蘸泻,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,541評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了嘲玫。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片悦施。...
    茶點(diǎn)故事閱讀 38,687評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出薪韩,到底是詐尸還是另有隱情,我是刑警寧澤煤蹭,帶...
    沈念sama閱讀 34,347評(píng)論 4 331
  • 正文 年R本政府宣布昼汗,位于F島的核電站肴熏,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏顷窒。R本人自食惡果不足惜蛙吏,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,973評(píng)論 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望鞋吉。 院中可真熱鬧鸦做,春花似錦、人聲如沸谓着。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,777評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)赊锚。三九已至治筒,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間舷蒲,已是汗流浹背耸袜。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,006評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留阿纤,地道東北人句灌。 一個(gè)月前我還...
    沈念sama閱讀 46,406評(píng)論 2 360
  • 正文 我出身青樓夷陋,卻偏偏與公主長(zhǎng)得像欠拾,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子骗绕,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,576評(píng)論 2 349

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