標籤:

matlab小工具-Matlab Coder

Matlab coder本身的作用是生成C/C++代碼,一般來說是配合Embedded coder給嵌入式環境使用,其本身在本身也可以配置的時候選擇運行的嵌入式環境。

但其很多奇奇怪怪的功能也被我用來做各種奇奇怪怪的事情了。。。。。。

在此簡單介紹一下

  • 運行加速
  • matlab動態鏈接庫分發
  • C/C++代碼生成
  • 數據限制
  • 運行內存和運算量檢查

首先大概聊一下coder的運行步驟(以最新的matlab coder為準),在command window輸入命令coder,自動就會打開coder的界面。一共有6(7)個步驟,分別為Select,Review,Define,Check,Generate,Finish。如果選擇轉為定點數據,那麼在Check之後還有多一個Convert步驟用來搞定數據轉換。

用一個官方圖來說明整個的使用步驟:

1) Select

首先選擇一個函數,腳本不能轉換,Project location一般是這個coder project的存儲位置,方便下次打開。

Numeric conversion 一般指的是數據格式的轉換,matlab裡面默認的數據類型都是雙精度浮點型,但是一般嵌入式環境下都不可能能夠承受如此的數據量和計算精度,需要對此數據做出限制。

2) Review

在Review中會檢查是否所有的函數都能被支持,而像evalin,assignin以及濾波器設計這種函數其實就不被支持。一般來講,C風格的所有函數都能被支持,具體關於哪些函數會被Coder支持,可以自行查閱mathwork官網。

3)Define

開頭就已經說過,只能轉換函數而不是腳本,所以需要定義函數的輸入輸出的矩陣規模和數據格式,其中如果有調用此函數的腳本,則可以使用腳本來確定輸入輸出數據的矩陣規模和數據格式。

當然也可以手動輸入輸入數據數據的矩陣規模和數據格式。

對於Global 的輸入,也可以手動輸入矩陣規模和數據格式。

4)check

在check中,會生成一個臨時性的mex文件(關於mex文件,稍後詳細解釋),運行調用此函數的腳本,然後核對matlab函數和臨時生成的mex的之間的差別,一般有問題都會在這裡指出,方便debug。

同時在這一步,因為調用實際使用的測試腳本,故可以查看每一條語句的調用次數。

5)Generate

關於Generate裡面有很多選項,關鍵著重講幾個,第一個是目標形式,可以是source code,可以是mex,可以是.a等等庫文件:

? MEX function

? C/C++ Static Library

? C/C++ Dynamic Library

? C/C++ Executable

? C/C++ source code

開始談幾個問題,一個是source code,主要是直接形成c/c++代碼,最關鍵的其實是輸入輸出矩陣的形式,我們在主函數中需要調用matlab function轉換的source code,這個介面是非常重要的。

這個時候需要提出矩陣的信息到底有哪幾部分構成:

i. 矩陣數據類型(ex. 復/實數)

ii. 矩陣數據表示類型(ex. 單/雙精度)

iii. 矩陣維數(向量/矩陣/三維向量)

iv. 矩陣規模(矩陣規模 2*2/4*4 矩陣)

vi. 矩陣數據

由此可以看出,除了最後一項是真正的數據以外,其他的都可以算作矩陣的「頭數據」。對於真正的數據,矩陣數據是以一維指針的形式傳遞,那麼就涉及到矩陣元素的排列順序是行優先還是列優先,在matlab和fortan中,數據以行優先的形式存放,在C/C++中,數據都已行優先的形式。具體的矩陣傳遞介面,matlab生成的代碼中,有相關的各種內存結構體參數提供,可以自行查閱生成的函數。

第二個選項是mex格式,mex格式的全稱是matlab executable,實質上是一個matlab的動態鏈接庫,另外matlab調用C函數的介面實際上也是通過mex介面,所以有多種用途,但選擇編譯為mex以後,選項只有JIT(just in time)選項,在官方文檔中,對JIT選項的解釋為integrated in file to save run time?(詳細的等我查證一下)。

後幾個都是源碼的各種庫,我都沒有用過,故就不說明了。

簡單談談matlabC函數的生成模式,

比如式子:C=AB,其中A,B,C都是矩陣

那麼在matlab中式子就是:

C=A*Bn

而如果仔細檢查生成的C代碼,每一步小計算式(最簡單的計算)C代碼包含:

a)C矩陣的內存大小檢查,如果不夠,就動態分配再次申請空間。

b)生成C矩陣的」頭信息「,之前說過「頭信息」內容。

c)計算的得到C矩陣的數據。

在這簡單談一下為什麼自動轉碼出來的代碼可能運行速度比自己寫的要差一點,我們常常用來黑C/C++的一個關鍵點,C/C++的內存管理實際上是有程序員而不是編譯器來控制的,雖然要求程序員需要能強的能力,但是也是最貼近底層的。

而在內存分配之前已經做好的情況下,每一步都要檢查內存實際上有時間的浪費,還有就是一句題外話,在運算迭代中,如果內存不足而需要頻繁的malloc/free的話,可能佔用時間比運算時間還要長。

好的,在此簡單切入主題,怎麼用這個Matlab coder來實現功能(運行加速/matlab動態鏈接庫分發/C/C++代碼生成/數據限制/運行內存和運算量檢查)

運行加速:生成mex函數,然後使用mex函數替代原來的函數,使用方法,就跟原來function的調用方法一樣,在沒改文件名的情況下,增加後綴「_mex」就好了。

matlab動態鏈接庫(可以用來分發給其他計算機的matlab):生成mex函數

C/C++:不需要我說了

數據限制:numberic conversion

運行內存和運算量檢查:

這個要著重說一下,全部的轉化完成以後,會得到一個report

其中在這個報告中,可以看到各個子函數的內存使用和計算複雜度(complexity)。

先說一下這個複雜度,我用profile這個工具對比過運行時間合格複雜度直接的差別,按道理來說,複雜度和運行時間應該是線性的,但實際上是有一點區別的,而且,report的複雜度應該跟數學式子的複雜度也是線性的,但也是有區別的。

後來我仔細研究過,發現報告中對於內存操作的複雜度跟實際有一定區別,因為這個,所以這個report中的複雜度我一般只用來橫向對比各個演算法,這點還是很好用的。

關於內存使用,對於每個子函數指標叫self_stack_size 和accum_size,其中分別代表在迭代計算中不能被釋放和可以被釋放的內存量,所以對於整個演算法的內存用兩實際為:

accumulated_stack_size = sum( self_stack_size1,self_stack_size2.....self_stack_sizeN) + max(accum_size1, accum_size2 ..., accum_sizeN)

其中1-N分別代表1-N個子函數。

Matlab Coder是一個非常強大的工具,除了我們能夠看到的轉碼,現在也發展出來了很多千奇百怪的副產物,先寫到這裡,一方面做自我總結,所以結構還是挺混亂的,另一方面,歡迎大家討論。

Reference

[1]cn.mathworks.com/help/c

[2]cn.mathworks.com/help/p

推薦閱讀:

如何用matlab畫天線的三維方向圖?
如何在 MATLAB 中實現車牌號圖片的識別?
matlab畫圖坐標軸標註問題,畫紅圈的地方應該怎麼畫?

TAG:MATLAB |