从MATLAB生成C代码的乐趣

比尔·周(Bill Chou), MathWorks

工程师们翻译低级语言如C成机器代码的编译器使用几十年。但是,它可以翻译像MATLAB的高级语言®用C语言编写代码?大多数工程师都同意这在理论上是可能的,但在实践中可行吗?生成的代码是可读的还是乱七八糟的?有效或浮肿吗?快或慢吗?它支持工业工作流程,还是金宝app仅仅支持研发?

本文将直面这些问题。它提供了使用MATLAB Coder™的技巧和最佳实践,以及Delphi、贝克休斯、iSonea和dorsaVi等公司成功应用生成代码的行业实例。

本文中的代码示例可用于下载。

比较MATLAB和C代码:一个乘法示例

下面乘两个输入简单的MATLAB功能。

给定标量输入,MATLAB Coder生成以下C代码:

如您所见,生成的代码清楚地映射回MATLAB代码。

同样的一段MATLAB代码,当给定两个矩阵输入时,生成三个嵌套-loops在C:

推荐三步迭代工作流程

上面所示的简单函数可以通过一个步骤实现。但是对于更实质性的项目,我们推荐使用三步迭代工作流的结构化方法(图1):

  1. 为代码生成准备算法。检查并修改MATLAB代码,以介绍底层C代码所需的实现注意事项,并使用MATLAB语言和功能支持金宝app代码生成。
  2. 使用默认设置测试MATLAB代码生成的准备情况。通过生成和执行MEX文件来检查运行时错误。如果成功,进行下一步。如果没有,则重复步骤1,直到可以生成MEX函数。
  3. 生成C代码或在步骤2中保留MEX函数。您可以对MATLAB代码进行迭代,以优化生成的C代码(用于外观、内存和速度)或MEX函数(用于性能)。
图1所示。用于生成代码的三步迭代工作流。

MATLAB的编码器的应用程序将引导您完成这个反复的过程,同时使你留在MATLAB环境中。它分析你的MATLAB代码提出的数据类型和尺寸的投入。它考验你的MATLAB代码是通过生成MEX函数代码生成做好准备,然后执行MEX函数来检查运行时错误(图2)。等效命令行功能提供相同的功能,因此可以作为脚本或功能的一部分生成代码。

图2.左:自动检查不支持用于代码生成的特征和功能。金宝app右:自动输入数据类型和大小的分析和建议。

下面的视频说明了这些步骤与产生卡尔曼滤波器来预测弹跳球的轨迹的一个例子。你会看到,三步迭代的过程,使我们能够生成原来的MATLAB结果,并能满足其需求的跟踪紧密匹配的代码。

实现约束

当你准备您的MATLAB算法生成代码,你需要考虑到的从MATLAB和C代码之间的差异导致实施的限制。这些包括:

  • 内存分配。在MATLAB中,内存分配是自动的。在C代码中,内存分配是手动的——它是静态分配的(使用静态),动态(使用Malloc.),或在堆栈上(使用局部变量)。
  • 基于阵列的语言。MATLAB提供了一组丰富允许简洁编码的数值算法阵列操作。C代码需要明确-loops表示相同的算法。
  • 动态类型。MATLAB在代码运行时自动确定数据类型和大小。C语言要求对所有变量和函数进行显式类型声明。
  • 多态性。MATLAB函数可以支持许多不同的输入类型金宝app,而C需要固定的类型声明。在顶层,必须指定预期的C函数声明。

让我们进一步研究多态性。多态可以根据您的输入给一行MATLAB代码不同的含义。例如,图3中显示的函数可能意味着标量乘法、点积或矩阵乘法。此外,您的输入可以是不同的数据类型(逻辑、整数、浮点、定点),它们可以是实数或复数。

图3.多态性例子。

MATLAB是一种强大的运算开发环境,正是因为你,你创建的算法并不需要担心实现细节。然而,对于同样的C代码,你必须指定哪些操作的意思。例如,如上所示MATLAB代码行可以转化成C代码本单行返回B * C:

或者,它可以被翻译成11行C代码两个矩阵相乘的循环:

下面使用视频一牛顿迭代算法来说明服用实现约束考虑在内的概念。你会看到用三步迭代工作流程完全原始MATLAB结果匹配生成的代码。

使用生成的代码:四个用例

一旦您使用MATLAB Coder从MATLAB算法生成了可读和可移植的C/ c++代码,您就有几个使用它的选项。例如,你可以:

  • 将MATLAB算法作为源代码或库集成到更大的软件项目中,如自定义模拟器或运行在pc和服务器上的软件包(观看视频(17)
  • 实现和验证嵌入式处理器,比如ARM的MATLAB算法®处理器和移动设备(观看视频(0:26))
  • 原型您的MATLAB算法作为一个独立的可执行的pc(观看视频(2:57))
  • 通过产生功能MEX调用编译的C / C ++代码加速的你的MATLAB代码计算密集部分(观看视频(21)

行业成功案例

  • 贝克休斯的动力学与遥测组根据序列预测算法生成一个DLL,并将其集成到PC上运行的地面解码软件中,从而在钻井作业中快速、可靠地解码井下数据。
  • dorsaVi从运动分析算法生成C ++代码,并将其编译成一个DLL,然后将其集成到分析运动员的运动来诊断损伤的PC上运行它们的C#应用​​程序。

  • VivaQuant根据心率监测算法生成定点C代码,并编译为ARM Cortex-M处理器。
  • 特尔斐生成了一个汽车雷达传感器对准算法的C语言代码,并在ARM10处理器上进行了编译。
  • Respiri根据声呼吸监测算法生成C代码,并将其编译为iPhone应用程序、Android应用程序和基于云的服务器软件。

多核代码生成和其他优化方法

在MATLAB中,-loops其迭代是彼此独立的,可以在平行简单地通过更换运行parfor.MATLAB编码器使用开放式多处理(OpenMP的)应用程序接口来支持共享存储器,多核代码生成从金宝appparfor循环。OpenMP是由许多金宝appC编译器的支持(例如,Microsoft®Visual Studio®专业的)。

您可以使用MATLAB编码器与嵌入式编码器®进一步优化代码效率和自定义生成的代码。Embedded Coder提供了对生成代码的函数、文件和数据的细粒度控制的优化。例如,你可以用存储类在生成的代码中控制全局变量的声明和定义,并使用代码生成模板在生成的代码中定制横幅和注释。Embedded Coder还通过使用代码替换库来提高代码效率,代码替换库使用为流行处理器优化的实现来替换某些操作符和函数,比如手臂皮层®——一个ARM的Cortex-M

测试生成的代码

当你开发的MATLAB算法,您可以创建单元测试,以验证算法产生预期的结果。测试采用笔试MATLAB单元测试框架可以重用,以验证生成的代码的行为与MATLAB算法相同。下面的视频展示了如何在Embedded Coder中结合在生成的独立代码或库上的软件在环(SIL)和处理器在环(PIL)测试中重用单元测试(图4)。

一个自动化的工作流

MATLAB编码器能够用于平移MATLAB算法成C代码自动化的工作流。有了这个工作流程,你花更少的时间编写和调试低级别的C代码和更多的时间开发,测试和优化设计。通过保持在MATLAB一个极好的参考,其中包括算法和测试平台,您可以更快地传播到C代码算法的改变。像MATLAB单元测试框架和嵌入式编码器SIL和PIL测试框架的自动化工具可以让你深入系统测试MATLAB代码和C代码两者。无论您是实现设计上运行传统的个人电脑Web服务器移动设备,或嵌入式处理器, MATLAB编码器将帮助您从MATLAB到C代码更快,更少的手动翻译错误。

文章刊登在MathWorks新闻和笔记

发布于2016 - 92987v00