加速MATLAB生成MEX函数的算法
你可以使用MATLAB®编码器™从MATLAB代码生成MEX函数。一个MEX函数是一个MATLAB可执行文件。它是生成的代码,可以从MATLAB内部调用。在MATLAB环境中工作时,可以使用MEX函数来加速MATLAB代码中计算密集型的部分。函数从MATLAB代码生成一个MEX函数MATLAB编码器App或使用codegen
在MATLAB命令行。
在本教程中,您将使用MATLAB编码器codegen
命令为MATLAB函数生成MEX函数。首先生成一个MEX函数,该函数只能接受具有固定的、预先分配的大小的输入。然后生成另一个MEX函数,该函数可以接受许多不同大小的输入。
教程文件
从文件夹中复制教程文件
到本地工作文件夹。在这里,matlabroot
帮助\ \工具箱\编码器\ \欧几里得例子
为MATLAB的安装文件夹,例如,matlabroot
C:\Program Files\MATLAB\R2019a
.要将这些文件复制到当前文件夹,运行这个MATLAB命令:
拷贝文件(fullfile (matlabroot,“帮助”,“工具箱”,“编码器”,“例子”,“欧几里得”))
euclidean_data.mat
,euclidean.m
,test.m
,test_2d.m
,build_mex_fixed.m
,build_mex_variable.m
文件。
MATLAB数据文件
euclidean_data.mat
包含两段数据:三维欧氏空间中的一个点和三维欧氏空间中其他几个点的集合。更具体地说:x
是一个3.
——- - - - - -1
表示三维欧几里得空间中一点的列向量。cb
是一个3.
——- - - - - -216
数组中。中的每一列cb
表示三维欧几里得空间中的一点。
MATLAB文件
euclidean.m
包含函数欧几里得
实现核心算法在这个例子中。函数取x
而且cb
作为输入。它计算之间的欧氏距离x
每一点cb
并返回这些量:列向量
y_min
,它等于in的列cb
它表示离x
.列向量
y_max
,它等于in的列cb
这代表了最远的点x
.二维向量
idx
它包含了向量的列下标y_min
而且y_max
在cb
.二维向量
距离
其中包含到的最小和最大的计算距离x
.
函数[y_min,y_max,idx,distance] = euclidean(x,cb)初始化最小距离为到cb第一个元素的距离将最大距离初始化为到cb第一个元素的距离idx (1) = 1;idx (2) = 1;距离(1)=规范(x-cb (: 1));距离(2)=规范(x-cb (: 1));求出cb中与x距离最小的向量求出cb中与x距离最大的向量为指数= 2:尺寸(cb, 2) d =规范(x-cb(:,指数));如果D < distance(1) distance(1)= D;idx(1) =指数;结束如果D > distance(2) distance(2)= D;idx(2) =指数;结束结束输出最小和最大距离向量y_min = cb (:, idx (1));y_max = cb (:, idx (2));结束
MATLAB脚本
test.m
加载数据文件euclidean_data.mat
进入工作区。它调用函数欧几里得
计算y_min
,y_max
,idx
,距离
.然后,脚本在命令行中显示计算出的数量。加载
euclidean_data.mat
是在调用核心算法之前执行的预处理步骤。显示结果是后处理步骤。负载测试数据负载euclidean_data.mat确定最近点和最远点以及相应的距离[y_min,y_max,idx,distance] = euclidean(x,cb);显示最近点的输出disp (最近点的坐标为:);disp (num2str (y_min '));disp ([最近点的索引是num2str (idx (1))));disp (['到最近点的距离是'num2str(距离(1))));disp(换行符);显示最远点的输出disp (最远点的坐标为:);disp (num2str (y_max '));disp ([最远点的索引是num2str (idx (2))));disp ([到最远点的距离是num2str(距离(2))));
MATLAB脚本
test_2d.m
是对test.m
二维欧几里得空间中的点。的内容test_2d.m
当您使用它来测试可变大小输入的MEX函数时,将在本教程后面展示。构建脚本
build_mex_fixed.m
而且build_mex_variable.m
包含从MATLAB代码生成静态C库的命令,分别接受固定大小和可变大小的输入。这些脚本的内容将在本教程后面生成C代码时显示。
提示
可以通过使用从MATLAB函数生成代码MATLAB编码器.不支持从MATLAB脚本生成代码。金宝app
使用测试脚本将预处理和后处理步骤与实现核心算法的函数分开。这种实践使您可以轻松地重用算法。生成实现核心算法的MATLAB函数的代码。您不为测试脚本生成代码。
生成的MEX函数MATLAB函数
运行原版本MATLAB代码
运行测试脚本test.m
在MATLAB。输出显示y
,idx
,距离
.
最近点的坐标为:0.8 0.8 0.4最近点的指数为171最近点的距离为0.080374最远点的坐标为:0 0 1最远点的指数为6到最远点的距离为1.2923
使MATLAB适合代码生成的代码
为了使您的MATLAB代码适合代码生成,您可以使用代码分析器和代码生成准备工具。当你输入代码时,MATLAB编辑器中的代码分析器会不断检查你的代码。它报告问题并建议修改,以最大化性能和可维护性。代码生成准备工具筛选MATLAB代码中不支持代码生成的特性和功能。金宝app
支持C/ c++代码生成的某些MATLAB内置函数和工具箱函数、类和系统对象具有特定的代码生成限制。金宝app中列出了这些限制和相关的使用说明扩展功能相应的参考页的部分。有关更多信息,请参见C/ c++代码生成支持的函数和对象金宝app.
开放
euclidean.m
在MATLAB编辑器中。MATLAB编辑器右上角的代码分析器消息指示器是绿色的。分析器没有检测到代码中的错误、警告或改进机会。函数声明之后,添加
% # codegen
指令:函数[y,idx,distance] =欧几里得(x,cb)% # codegen
% # codegen
指令提示代码分析器识别特定于代码生成的警告和错误。Code Analyzer消息指示器变成红色,表示它已检测到代码生成问题。
若要查看警告消息,请将光标移动到带下划线的代码片段。警告指示代码生成需要这些变量
idx
而且距离
在下标之前完全定义。出现此警告是因为代码生成器必须在这些变量第一次出现在代码中时确定它们的大小。若要修复此问题,请使用的
函数同时分配和初始化这些数组。初始化最小距离为到cb第一个元素的距离将最大距离初始化为到cb第一个元素的距离Idx = ones(1,2);距离= ones(1,2)*norm(x-cb(:,1));
Code Analyzer消息指示器再次变为绿色,表示它没有检测到任何代码生成问题。
有关使用代码分析器的详细信息,请参见使用代码分析器检查代码中的错误和警告.
保存文件。
要运行代码生成准备工具,请调用
coder.screener
函数从MATLAB命令行:coder.screener (“欧几里得”)
该工具不会检测到任何代码生成问题
欧几里得
.有关更多信息,请参见代码生成准备工具.中不支持代码生成准备工具金宝appMATLAB在线™.
请注意
代码分析器和代码生成准备工具可能无法检测到所有的代码生成问题。在消除这些工具检测到的错误或警告之后,通过使用生成代码MATLAB编码器以确定您的MATLAB代码是否有其他遵从性问题。
方法编译代码MATLAB编码器应用。在这里,编译指从MATLAB代码生成C/ c++代码。
请注意
编译MATLAB代码是指从MATLAB代码生成C/ c++代码。在其他上下文中,术语编译可以指C/ c++编译器的操作。
定义输入类型
因为C使用静态类型,代码生成器必须在代码生成时确定MATLAB文件中所有变量的类、大小和复杂性,也称为编译时.因此,在为文件生成代码时,必须为入口点函数指定所有输入参数的属性。一个入口点函数是一个顶级的MATLAB函数,您可以从中生成代码。
方法生成代码时codegen
命令,使用arg游戏
选项,为入口点函数指定示例输入参数。代码生成器使用此信息来确定输入参数的属性。
在下一步中,使用codegen
命令从入口点函数生成MEX文件欧几里得
.
生成并验证MEX函数
构建脚本build_mex_fixed.m
包含用于生成和验证的MEX函数的命令euclidean.m
.要验证MEX函数,需要运行测试脚本测验
调用MATLAB函数欧几里得
替换为对生成的MEX函数的调用。
加载测试数据负载euclidean_data.mat生成欧几里得代码。M和密码原。使用测试数据作为示例输入。使用test.m验证MEX。codegen报告euclidean.marg游戏{x, cb}以及测验
默认情况下,
codegen
生成一个名为euclidean_mex
在当前文件夹中。的
报告
选项指示codegen
生成代码生成报告,您可以使用该报告调试代码生成问题,并验证MATLAB代码是否适合代码生成。的
arg游戏
选项指定入口点函数的样例输入参数欧几里得
.代码生成器使用此信息来确定输入参数的类、大小和复杂性。你可以使用
以及
选项运行测试文件test.m
.此选项替换对的调用欧几里得
在测试文件中调用euclidean_mex
.
有关代码生成选项的详细信息,请参见codegen
.
运行构建脚本
build_mex_fixed.m
.代码生成器生成一个MEX函数
euclidean_mex
在当前工作文件夹中。输出结果为:
代码生成成功:查看报告。运行测试文件:'test',带有MEX函数'euclidean_mex'。最近点的坐标为:0.8 0.8 0.4最近点的指数为171最近点的距离为0.080374最远点的坐标为:0 0 1最远点的指数为6到最远点的距离为1.2923
若要在“报表查看器”中查看代码生成报告,请单击查看报告.
如果代码生成器在代码生成过程中检测到错误或警告,则报告将描述问题并提供到有问题的MATLAB代码的链接。看到代码生成报告.
提示
使用构建脚本在命令行生成代码。构建脚本自动执行一系列在命令行上重复执行的MATLAB命令,从而节省时间并消除输入错误。
生成可变大小输入的MEX函数
您为之生成的MEX函数euclidean.m
只能接受与您在代码生成期间指定的示例输入大小相同的输入。然而,对应的MATLAB函数的输入数组可以是任何大小。在本教程的这一部分中,您将从euclidean.m
它接受可变大小的输入。
假设你想要维数x
而且cb
在生成的MEX函数中具有以下属性:
两者的第一个维度
x
而且cb
大小可以变化到3.
.第二个维度
x
是固定的,有价值的1
.第二个维度
cb
大小可以变化到216
.
要指定这些输入属性,可以使用coder.typeof
函数。coder.typeof (A, B, 1)
指定具有相同类和复杂度的可变大小输入一个
和由size向量的相应元素给出的上界B
.使用构建脚本build_mex_variable.m
使用coder.typeof
在生成的MEX函数中指定可变大小输入的属性。
加载测试数据负载euclidean_data.mat%使用编码器。Typeof指定可变大小的输入eg_x =编码器。typeof (x, [3 1], 1);eg_cb =编码器。typeof (cb [216], 1);生成欧几里得代码。M使用编码器。要指定的类型%示例输入的上限codegen报告euclidean.marg游戏{eg_x, eg_cb}
您可以验证新的MEX功能euclidean_mex
接受与的维度不同的输入x
而且cb
.测试脚本test_2d.m
创建输入数组x2d
而且cb2d
它们是二维的x
而且cb
,分别。然后调用MATLAB函数欧几里得
通过使用这些输入参数。
加载测试数据负载euclidean_data.mat创建x和cb的二维版本: x2d = x (1:2);cb2d = cb (1:2, 1:6:216);确定最近点和最远点以及相应的距离[y_min,y_max,idx,distance] = euclidean(x2d,cb2d);显示最近点的输出disp (最近点的坐标为:);disp (num2str (y_min '));disp ([最近点的索引是num2str (idx (1))));disp (['到最近点的距离是'num2str(距离(1))));disp(换行符);显示最远点的输出disp (最远点的坐标为:);disp (num2str (y_max '));disp ([最远点的索引是num2str (idx (2))));disp ([到最远点的距离是num2str(距离(2))));
运行test_2d.m
产生输出:
最近点的坐标为:0.8 0.8最近点的指数为29距离最近点的距离为0.078672最远点的坐标为:0 0最远点的指数为1距离最远点的距离为1.1357
运行测试脚本test_2d.m
通过呼叫欧几里得
替换为对euclidean_mex
,使用coder.runTest
.
coder.runTest (“test_2d”,“欧几里得”)
x
而且cb
.
下一个步骤
目标 | 更多的信息 |
---|---|
了解MATLAB内置函数和工具箱函数、类和系统对象的代码金宝app生成支持 |
|
生成c++ MEX代码 |
|
交互式地创建和编辑输入类型 |
|
优化生成代码的执行速度或内存使用 |
|
了解代码生成报告 |
|
参见在MATLAB分析器中生成的MEX函数的执行时间和代码覆盖率 |