MATLAB + VS 2015混合编程并调试

对于大规模重复的运算,为了提高运算速度,可以将部分核心代码用C++来实现,用编译器编译成动态可执行文件(mex文件),在MATLAB中直接调用。

个人亲历,有一段Monte-Carlo仿真的MATLAB代码,在Intel 8700K+32G的机器上,运行时间在1周左右,经过C++重构核心代码后,可以在2天内完成。同时,由于内存的占用降低,可以进行更大规模的仿真。

MATLAB版本:R2018b;C++编译器:Visual Studio 2015 Professional

关于不同版本MATLAB支持的编译器,参考官网链接。

一、在Visual Studio中编写C++文件。

1.1 新建一个win32项目

项目名最好与函数名一致,注意应用程序类型设置为DLL。

1.2 配置项目属性。

  • 在项目名称上右键 -> 属性即可打开项目属性页。
  • 配置属性->配置管理器->活动平台解决方案 -> 新建解决方案平台 -> x64;
  • 配置属性->C++ ->附加包含目录,加入MATLAB目录下的\extern\include 路径,默认为C:\Program Files\MATLAB\R2018b\extern\include;
  • 配置属性->链接器->附加库目录,加入MATLAB目录下的\extern\lib\win64\microsoft路径,默认为C:\Program Files\MATLAB\R2018b\extern\lib\win64\microsoft;
  • 配置属性->链接器->输入->附加依赖项, 添加libmx.lib,libeng.lib,libmat.lib,libmex.lib这四个lib文件;
  • 配置属性->链接器->常规->输出文件,改为x64\Debug\vlda.mexw64 (vlda为项目名称);
  • 配置属性->配置属性->常规->目标文件扩展名,改为.mexw64;
  • 新建模块定义文件,vlda.def,内容为
LIBRARY;"vlda"  // vlda为项目名称 
EXPORTS mexFunction
  • 配置属性->链接器->输入->模块定义文件,vlda.def;

1.3 编写函数文件

在源文件里面已有vlda.cpp(vlda为项目名称),在vlda.cpp中编写MEX函数文件。

mex函数的编写注意事项:

  • 注意检查输入的参数类型参数数目,MATLAB默认的数据类型为double,一旦不匹配,MATLAB调用时会直接崩溃;
  • 注意内存泄漏,分配的内存,记得释放掉;
  • MATLAB 中的parfor可以在C++ 中轻松使用OpenMP实现,具体为添加库文件
# include "omp.h"

同时,在for循环前加上如下预编译指令

#pragma omp parallel for 
  • 使用OpenMP时,配置属性->C++ ->语言->OpenMP支持,选为"是";

1.4 生成解决方案

编写好mex函数后,在项目名称上右键->生成,从而进行编译,生成.mex64文件。

二、调试

  • 将生成的.mexw64拷贝到MATLAB当前目录。
  • 菜单栏:调试->附加到进程->选择MATLAB进程,附加到进程后,会经历较长时间的符号加载过程;
  • 如果符号加载时间过长,可以通过设置符号位置来解决,菜单栏:调试->选项->符号->勾选Microsoft符号服务器;
  • 在源代码vlda.cpp中设置断点;
  • 在MATLAB中调用.mex64文件,会跳转到VS 2015 中的断点,F10可单步执行;
  • 调试过程中修改vlda.cpp,重新生成解决方案,将新生成的mexw64文件拷贝到MATLAB当前目录,此时,需要在matlab中clear掉原来的mexw64文件,即运行命令
clear vlda.mexw64

三、发布

对于比较简单的程序,直接用Debug版本的也没什么问题,但最好还是使用Release版本。

  • 配置属性->配置管理器->活动解决方案配置->Release ,其他设置参照1.2配置项目属性设置。
  • 如果mexw64文件需要拷贝到别的电脑上运行,可以考虑采用静态编译。配置属性->C++ ->代码生成->运行库:多线程(/MT);配置属性->常规->MFC的使用:在静态库中使用MFC。

四、总结

将部分核心代码用C++实现后,能够极大的提高运算速度,同时降低内存的使用。另一方面,借助于OpenMP,可以很方便的实现并行计算,将多核CPU的利用率维持在100%。

你可能感兴趣的:(MATLAB + VS 2015混合编程并调试)