matlab代码改写C++代码并使用MKL加速-问题记录
运行现有代码、配置本地环境
用领导的代码在本地运行,借机配置Eigen库和Intel的MKL
Eigen库VS2022建议使用vcpkg安装,但vcpkg使用需要学习时间,所以直接用Nuget安装了
安装之后报错找不到mkl.h
-
在官网下载oneMKL(https://www.intel.cn/content/www/cn/zh/developer/tools/oneapi/onemkl-download.html)
下载后解压并安装,路径不可以有汉字,解压后安装是自动进行的 -
找到安装路径,我电脑里默认的C:\Program Files (x86)\Intel\oneAPI
在这个路径里每个文件夹都打开看看,看看哪里是.dll/.lib/.h文件。记录下来,后面在VS2022配置路径时要用到 -
参考了这个链接进行VS2022和MKL库的配置(https://www.bilibili.com/video/BV1fE411y7Gf/?spm_id_from=333.880.my_history.page.click&vd_source=82f9c74857f9fcc1a66ba80287144dac)
由于网上找的和视频里的,都和下载的不完全一样,所以第二步中每个路径都看看,知道谁在哪里就很重要,配置的时候才能知道用哪个路径。
至此,领导的代码可以在本地运行。注意:在本地运行并不是可以在Vs中进行调试,而是正确生成解决方案之后,可以正常运行生成的可执行程序。 因为新建项目时选择的是新建一个动态链接库项目,所以不能在VS中调试。
C#代码调用C++封装的dll
在操作之前分别跟练了两个示例:
- https://learn.microsoft.com/zh-cn/cpp/build/walkthrough-creating-and-using-a-dynamic-link-library-cpp?view=msvc-170 (此为示例1)
- https://www.jb51.net/article/143382.htm (此为示例2)
由于我对C++的不熟悉,所以先跟练了示例1,全当是为了减轻对未知的恐惧,还有了解大致的思路。
在此基础上,示例2使我收获颇丰。需要注意的是,示例2中有两篇C#代码,分别是Program类和MyClassWrapper类。这是两个方法,不是同时使用的。如果你很累,脑袋很乱没法认真思考的时候这里容易疏忽。
-
根据示例2和领导的代码,新建一个Windows桌面向导中的动态链接库项目。先写头文件,再去源文件里写方法的具体实现。写时需要注意 从dll导出这个类里自己的方法和别人调用这个dll时要调用的方法。比如下图
我在源文件中是直接写的Calculate()方法的实现,还没有声明自变量,所以有很多错误。大致都是说Eigen没有成员PolynomialSolver,及类似错误。这是由于缺少引用文件导致的,补充下就好了include内容
#include <Eigen/Eigen> #include <unsupported/Eigen/Polynomials>
-
根据示例2中C#代码中的Program类,创建一个C#控制台项目并编写代码进行调用。可以正常运行,但是运算速度特别慢。究其原因是在新建的C++ dll项目中没有使用MKL加速。
C++使用MKL加速
- 在C++代码的最上方添加
#define EIGEN_USE_MKL_ALL
和#define EIGEN_VECTORIZE_SSE4_2
,添加后再次出现找不到mkl.h文件错误。经过对oneMKL的修复、重新配置路径、运行配置环境变量、重启等一系列操作,不好使。最后考虑到我这个项目用的是64位程序,所以在对MKL引用的库中删除了bin32、lib32等带32的目录,问题解决。注意:并不是可能需要的所有路径都链接上就好使,多了也不行。 - 接下来出现DllNotFoundException,见下图
经过一些排查,比如对比两个项目的文件引用、对比两个项目中包含的dll文件,没有找到问题。最终使用VS自带的dumpbin工具查找封装的dll文件有哪些依赖(https://blog.csdn.net/weixin_44120025/article/details/118651103) 用everything找到具体的文件,直接放到C#项目的bin/Debug文件夹下。问题解决。注意:这个方法简单粗暴,但是感觉解决的不够明白彻底。希望有后续。 - 调用的dll文件运行过程中出现新的异常
计划:先检查输入、在给C++加异常处理