1、MATLAB 程式設計入門篇:通用運算式MATLAB 程式設計入門篇程式碼與記憶體之最佳化張智星jangmirlab.orghttp:/mirlab.org/jang清大資工系 多媒體檢索實驗室MATLAB 程式設計入門篇:通用運算式n 重點說明n 6.5 版之前, MATLAB 執行效率非常倚賴程式碼的向量化n 6.5 (含)版後, MATLAB 引進了 JIT 加速器,程式碼向量化的重要性相對降低。n 同學們仍須瞭解程式碼向量化的實作方法、優缺點。n 本章範例之執行環境n OS: Windows 7n CPU: Intel Core i7-2670QM, 2.20GHzn RAM: 8GB
2、n MATLAB: 7.12.0.635 (R2011a)2-1 程式碼的向量化MATLAB 程式設計入門篇:通用運算式n 6.5 版之前, MATLAB 程式環境是一個傳統的解譯器( Interpreter),在執行 MATLAB的程式碼時,會進行下列動作 :n 逐列對程式碼轉換為 p-code,這是 MATLAB 可以解讀的格式。n 對產生的 p-code 進行逐列執行。MATLAB 程式運作流程 (I)MATLAB 程式設計入門篇:通用運算式n 在執行每一列 p-code 時,都還包含一些經常開銷( Overhead)n 若該列執行需要大量運算,經常開銷就會顯得很渺小而不會拖累程式執行速
3、度。n 若該列只是簡單的運算,那經常開銷的比例就會相對提高。n 若該列是放在迴圈內,那麼程式碼的執行速度就會被這些經常開銷大幅拖慢。MATLAB 程式運作流程 (II)MATLAB 程式設計入門篇:通用運算式n 若要加快執行速度n MATLAB 6.5 版之前,就要盡量不使用迴圈 ,而盡量改用向量化的運算,以降低經常開銷的比例。 n MATLAB 6.5 版(含)之後,已經加入了 JIT-Accelerator,有效地降低了經常開銷的比例,同時也使得向量化程式碼的重要性越來越低。n JIT: Just-In-Timen 對向量化運算來進行說明,主要著眼點在於:n 很多舊的程式碼還是包含向量化的
4、運算。n MATLAB 6.5 之前的版本,向量化的運算還是提高執行效率的主要關鍵。n 某些情況下, JIT-Accelerator 的效能無法完全發揮,還是需要配合向量化的運算才可以讓程式碼更有效率。 MATLAB 程式碼的向量化MATLAB 程式設計入門篇:通用運算式傳統範例 (I)n 計算 n 項調和數列的總和,若使用 for 迴圈,當 n = 100,000 時,可計算其執行時間如下:n 範例 2-1: hsum01.mticn = 100000;total = 0;for i = 1:ntotal = total+1/i;endtocelapsed_time =2.63000MATL
5、AB 程式設計入門篇:通用運算式n 由上可知,當 n = 100,000 時,使用 for 迴圈的程式碼約需 2.63 秒才能執行完畢。若改用向量化的運算,可計時如下:n 範例 2-2: hsum02.mticn = 100000;sequence = 1:n;total = sum(1./sequence);tocelapsed_time =0.0600傳統範例 (II)MATLAB 程式設計入門篇:通用運算式提示n 上述的測試時間是根據 Pentium-450, 256 MB RAM在 MATLAB 6.1 所得到的結果。如果你的電腦更快,計算時間的差異性就不會那麼顯著。n 若使用我目前環
6、境進行測試:n hsum01 0.009773 secn hsum02 0.008938 secn 在 MATLAB 6.5 版之後,採用了 JIT (Just-In-Time) 的編譯技術,因此向量化和非向量化的程式執行速度差異較小 。MATLAB 程式設計入門篇:通用運算式n 要能夠熟練地運用向量化的運算,有下列三個訣竅:n 對矩陣的索引( Indexing)非常熟悉。n 對 MATLAB 可用的內建( Built-in)指令非常熟悉。n 對問題本身的解法非常瞭解。程式碼向量化的要訣MATLAB 程式設計入門篇:通用運算式n 若要對一個矩陣 x 的每一個直行乘上向量 a 的每一個元素,我們可使用內建的 diag 指令來達成此功能,例如:n 範例 2-3: colMultiply01.mn 此為以空間換取時間的範例。x = 1 2 3; 1 1 1; a = 3 2 1; y = x*diag(a)y =3 4 33 2 1 矩陣直行乘法