一直以來,工程師都手工編寫 C 語言實現算法再通過編譯器編譯為機器代碼。能否使用編碼器將 MATLAB 這樣的高級語言翻譯成 C 語言?大多數工程師認為這是可行的——理論來說。
但實際上是否可行?
生成的代碼是可讀性如何?效率如何?執行速度如何?
面向工業流程或只是處于研發階段?
MATLAB Coder 的使用技巧和最佳實踐可以直接回答以上問題,這里還將分享行業將 MATLAB 生成 C 代碼的成功經驗和應用案例(包括 Delphi、Baker Hughes、iSonea、dorsaVi 等)。
- 對比 MATLAB 和 C 代碼 -
以下面這個簡單的 MATLAB 乘法函數為例。
function c = myMult (a, b)
% Multiply two inputs
c = a * b;
給定標量輸入,MATLAB Coder 可以生成下面的 C 代碼:
#include "myMult.h"
doublemyMult (doublea,doubleb)
{
return a *b;
}
正如所見,生成的代碼清楚地與 MATLAB 代碼相映射。
同樣的 MATLAB 代碼,當給定兩個矩陣輸入時,在生成的 C 代碼中會包含三層嵌套的 for 循環:
#include "myMult.h"
void myMult (const doublea[12],const doubleb[20],doublec[15],)
{
inti0;
inti1;
inti2;
for(i0 = 0; i0 < 3; i0++)? {
for(i1 = 0; i1 < 5; i1++)? {
c[i0 + 3 * i1] = 0.0;
for(i2 = 0; i2 < 4; i2++)? {
c[i0 + 3 * i1] += a[i0 + 3 * i2] * b[i2 + (i1 << 2 )];
}
}
}
}
推薦!
- 三步迭代工作流程 -
上述簡單的函數可以在一個步驟中實現。但是對于更多的實際項目來說,我們推薦使用三步迭代工作流程的結構化方法:
準備好需要生成代碼的算法。檢驗并修改 MATLAB 代碼來引入生成 C 代碼的要素,使用支持代碼生成的 MATLAB 語言和函數。
使用默認設置測試 MATLAB 代碼生成時的可讀性。通過生成并執行 MEX 文件來檢查運行中的錯誤。如果運行成功,則進行下一步。如果不成功,則重復第一步直到能生成一個 MEX 函數。
生成 C 代碼或保留第二步的 MEX 函數。你可以通過迭代 MATLAB 代碼來優化生成的 C 代碼(外觀、內存和速度)或 MEX 函數(性能)。
MATLAB Coder app 會引導你在MATLAB環境中完成這一迭代過程:
分析你的 MATLAB 代碼,提供輸入數據的類型和大小
生成一個 MEX 函數,測試你的 MATLAB 代碼是否準備好
執行 MEX 函數,檢查運行錯誤
等效的命令行函數提供同樣的功能,因此你可以生成代碼作為腳本或函數的一部分。
左:自動檢測不支持代碼生成的特征和函數。
右:自動分析和建議輸入數據的類型和大小。
- 實際生成代碼的限制 -
當你準備好代碼生成的 MATLAB 算法時,你需要考慮到 MATLAB 和 C 代碼的差別導致的限制,包括:
內存分配。在 MATLAB 中,內存分配是自動的。在 C 代碼中,內存分配則是手動的——可以是靜態(static),動態(malloc),或者堆棧(局部變量)。
數組語言。MATLAB 提供豐富的數組運算集,可以簡化數值算法的代碼。C 代碼則需要用明確的 for 循環表達同樣的算法。
動態類型。MATLAB 可以在運行時自動地確定數據類型和大小。C 語言要求對所有變量和函數進行明確的類型聲明。
多態性。MATLAB 函數可以支持多種不同輸入類型,而 C 語言要求固定的類型聲明。在頂層,你必須明確預期的 C 函數聲明。
這里詳細說明多態性。多態性可以根據你的輸入給一行 MATLAB 代碼賦予不同的意義。例如,圖中的函數可以表示標量乘法,向量點積,或者矩陣乘法。另外,你的輸入可以是不同的數據類型(邏輯值,整形,浮點數,定點數),也可以是實數或復數。
MATLAB 強大的算法開發環境體現于當你創建算法時,不需要考慮實現的具體細節。但是,對于等效的 C 代碼,你不得不明確操作的含義。例如上述案例,MATLAB 代碼可以被翻譯成一行返回 B*C 的值的 C 代碼:
doublefoo (doubleb,doublec)
{
return b * c;
}
或者,它可以被翻譯成 11 行由 3 層 for 循環組成的將兩個矩陣相乘的 C 代碼:
void myMult (const doublea[12],const doubleb[20],doublec[15],)
{
inti0;
inti1;
inti2;
for(i0 = 0; i0 < 3; i0++)? {
for(i1 = 0; i1 < 5; i1++)? {
c[i0 + 3 * i1] = 0.0;
for(i2 = 0; i2 < 4; i2++)? {
c[i0 + 3 * i1] += a[i0 + 3 * i2] * b[i2 + (i1 << 2 )];
}
}
}
}
- 多核代碼生成和其他優化方法 -
在 MATLAB 中,迭代過程互相獨立的 for 循環可以簡單地通過將 for 替換為 parfor 實現并行運行。MATLAB Coder 使用 Open Multiprocessing (OpenMP)應用程序接口來支持 parfor 循環中的共享內存和多核代碼生成。OpenMP 被很多 C 編譯器(例如 Microsoft Visual Studio Professional)支持 。
你可以使用有 Embedded Coder 的 MATLAB Coder 來進一步優化代碼效率并定制生成的代碼。Embedded Coder 提供對生成的代碼的函數、文件和數據的細粒度控制的優化。
例如你可以使用存儲類來控制生成的代碼中全局變量的聲明和定義,并使用代碼生成模板來自定義生成的代碼中的橫幅和注釋。Embedded Coder 還可以通過使用代碼替換庫來提高代碼效率,代碼替換庫可以使用為 ARM Cortex-A 和 ARM Cortex-M 等流行的處理器而優化過的實現來替換某些運算符和函數。
- 測試生成的代碼 -
在開發 MATLAB 算法時,你可以創建單元測試來驗證算法是否能產生你預期的結果。使用 MATLAB 單元測試框架編寫的測試可以被用于驗證生成的代碼的運行情況是否與 MATLAB 算法一致。使用 Embedded Coder 你可以結合 SIL 和 PIL 在測試生成的獨立代碼或庫時實現單元測試的重用。
- 自動化工作流程 -
MATLAB Coder 保證了將 MATLAB 算法轉換為 C 代碼的自動化工作流程。這個工作流程可以花費更少的時間編寫和調試低C代碼,而有更多的時間用于開發、測試和調優設計。
通過 MATLAB 中的黃金參考,包括算法和測試平臺,你可以更快地將算法移植到 C 代碼中。MATLAB 單元測試以及 Embedded Coder 的 SIL 和 PIL 測試框架等自動化工具,可以讓你全面而系統地測試MATLAB 代碼和 C 代碼。無論你是在傳統 的PC端,Web 服務器,移動設備,還是嵌入式處理器上實現設計,MATLAB Coder 將幫助您更快地從 MATLAB 生成 C 代碼,并減少手工錯誤。
-
數據
+關注
關注
8文章
7067瀏覽量
89108 -
函數
+關注
關注
3文章
4333瀏覽量
62687 -
C代碼
+關注
關注
1文章
89瀏覽量
14307
發布評論請先 登錄
相關推薦
評論