几十年来,工程师们一直在使用编译器将像C这样的低级语言翻译成机器码。但是否有可能翻译一种高级语言,如MATLAB®用C语言编写代码?大多数工程师都同意这在理论上是可能的,但在实践中可行吗?生成的代码是可读的还是乱七八糟的?有效或浮肿吗?快或慢吗?它支持工业工作流程,还是万博1manbetx仅仅支持研发?
本文将直面这些问题。它提供了使用MATLAB Coder™的技巧和最佳实践,以及Delphi、贝克休斯、iSonea和dorsaVi等公司成功应用生成代码的行业实例。
本文中的代码示例可用于下载。
比较MATLAB和C代码:一个乘法示例
下面的简单MATLAB函数将两个输入相乘。
给定标量输入,MATLAB Coder生成以下C代码:
如您所见,生成的代码清楚地映射回MATLAB代码。
同样的一段MATLAB代码,当给定两个矩阵输入时,生成三个嵌套为
-C中的循环:
推荐的三步迭代工作流
上面所示的简单函数可以通过一个步骤实现。但是对于更实质性的项目,我们推荐使用三步迭代工作流的结构化方法(图1):
- 为代码生成准备算法。检查并修改MATLAB代码,以介绍底层C代码所需的实现注意事项,并使用MATLAB支持万博1manbetx代码生成。
- 使用默认设置测试MATLAB代码生成的准备情况。通过生成和执行MEX文件来检查运行时错误。如果成功,进行下一步。如果没有,则重复步骤1,直到可以生成MEX函数。
- 生成C代码或在步骤2中保留MEX函数。您可以对MATLAB代码进行迭代,以优化生成的C代码(用于外观、内存和速度)或MEX函数(用于性能)。
MATLAB Coder应用程序将引导您完成此迭代过程,同时使您能够留在MATLAB环境中。它分析您的MATLAB代码,为您的输入提出数据类型和大小。它通过生成MEX函数来测试您的MATLAB代码是否准备好生成代码,然后执行MEX函数以检查运行时错误等效的命令行函数提供相同的功能,因此您可以将代码作为脚本或函数的一部分生成。
下面的视频以生成卡尔曼滤波器来预测弹跳球的轨迹为例说明了这些步骤。您将看到,三步迭代过程使我们能够生成与原始MATLAB结果非常匹配并满足其跟踪要求的代码。
从MATLAB代码生成C代码4:34
实施约束
在准备代码生成的MATLAB算法时,需要考虑由于MATLAB和C代码之间的差异而产生的实现约束。这些措施包括:
- 内存分配。在MATLAB中,内存分配是自动的。在C代码中,内存分配是手动的——它是静态分配的(使用
静态
),动态(使用马洛克
),或在堆栈上(使用局部变量)。 - 基于数组的语言。MATLAB提供了一组丰富的数组操作,允许对数值算法进行简洁的编码。C代码需要显式的
为
-loops表示相同的算法。 - 动态类型。MATLAB在代码运行时自动确定数据类型和大小。C语言要求对所有变量和函数进行显式类型声明。
- 多态性。MATLAB函数可以支持许多不同的输入类型万博1manbetx,而C需要固定的类型声明。在顶层,必须指定预期的C函数声明。
让我们进一步研究多态性。多态可以根据您的输入给一行MATLAB代码不同的含义。例如,图3中显示的函数可能意味着标量乘法、点积或矩阵乘法。此外,您的输入可以是不同的数据类型(逻辑、整数、浮点、定点),它们可以是实数或复数。
MATLAB是一个强大的算法开发环境,这正是因为在创建算法时,您不需要担心实现细节。但是,对于等效的C代码,您必须指定操作的含义。例如,上面显示的MATLAB代码行可以转换为返回B*C的这一行C代码:
或者,它可以被翻译成11行C代码为
两个矩阵相乘的循环:
下面的视频使用Newton-Raphson算法来说明考虑实现约束的概念。您将看到使用三步迭代工作流生成的代码与原始MATLAB结果完全匹配。
用MATLAB编码器寻址实现约束11:24
使用生成的代码:四个用例
一旦您使用MATLAB Coder从MATLAB算法生成了可读和可移植的C/ c++代码,您就有几个使用它的选项。例如,你可以:
- 将MATLAB算法作为源代码或库集成到更大的软件项目中,如自定义模拟器或运行在pc和服务器上的软件包(观看视频(17)
- 在嵌入式处理器(如ARM)上实现并验证MATLAB算法®处理器和移动设备(观看视频(0:26))
- 原型您的MATLAB算法作为一个独立的可执行的pc(观看视频(2:57))
- 通过生成调用已编译的C/C++代码的MEX函数,加速MATLAB代码中计算密集的部分(观看视频(21)
行业成功案例
- 贝克休斯的动力学与遥测组根据序列预测算法生成一个DLL,并将其集成到PC上运行的地面解码软件中,从而在钻井作业中快速、可靠地解码井下数据。
dorsaVi从运动分析算法生成C++代码,并将其编译成动态链接库,然后将其集成到PC上运行的C应用程序中,该程序分析运动员的运动以诊断损伤。
- VivaQuant根据心率监测算法生成定点C代码,并编译为ARM Cortex-M处理器。
- 特尔斐生成了一个汽车雷达传感器对准算法的C语言代码,并在ARM10处理器上进行了编译。
- 呼吸根据声呼吸监测算法生成C代码,并将其编译为iPhone应用程序、Android应用程序和基于云的服务器软件。
多核代码生成和其他优化方法
在MATLAB中,为
-迭代相互独立的循环可以通过替换为
具有parfor
. MATLAB编码器使用开放式多处理(OpenMP)应用程序接口来支持共享内存,从万博1manbetxparfor
循环。OpenMP受到许多C编译器万博1manbetx(例如Microsoft)的支持®Visual Studio®专业的)。
测试生成的代码
在开发MATLAB算法时,可以创建单元测试来验证算法是否产生了预期的结果。使用MATLAB单元测试框架可以重用,以验证生成的代码的行为与MATLAB算法相同。下面的视频展示了如何在Embedded Coder中结合在生成的独立代码或库上的软件在环(SIL)和处理器在环(PIL)测试中重用单元测试(图4)。
一个自动化的工作流
文章刊登在MathWorks新闻和笔记