如何利用GPU(CUDA)加速Matlab程序?

时间:2024-05-19 22:19:29

在Matlab中调用GPU的CUDA API进行并行加速,主要有两种途径:

1)对现有Matlab代码的简单改写,调用Matlab中支持CUDA的函数进行加速。

2)将C语言的CUDA函数封装成库,在Matlab中进行调用。

前者简单方便,效率低;后者效率高,稍微麻烦。

       一、matlab中直接的gpu加速计算

matlab中直接做GPU计算分为三个步骤。

(1)数据的初始化

使用gpuArray()则可生成gpu端数据,a=gpuArray(b),即为将cpu端数据b拷贝到gpu端的a中。

     (2)对GPU数据进行操作

      可以使用matlab中的库函数对gpuarray直接进行操作。

(3)把GPU上的数据回传给CPU

使用gather()则可将gpu端的数据传回cpu端。

 

二、 Matlab中调用CUDA C

  1. 配置环境

(1)Matlab环境配置:

1mex -setupC  配置编译器。注:若c语言编译器和matlab版本不匹配系统会报错:找不到编译器活SDK等。配置成功后显示下图所示信息。

如何利用GPU(CUDA)加速Matlab程序?

 

2 mex -setup c++ 选择语言,在编译器配置成功后选择所需的语言。配置成功后显示如下图所示信息。如何利用GPU(CUDA)加速Matlab程序?

 

Matlab环境配置结束。

(2)系统环境变量配置

打开电脑中的高级系统设置。选择环境变量,在系统变量的Path变量中添加所安装matlab文件夹中的extern\lib\win64\microsoft,matlab\lib\win64和matlab\bin\win64。如下图所示

如何利用GPU(CUDA)加速Matlab程序?如何利用GPU(CUDA)加速Matlab程序?如何利用GPU(CUDA)加速Matlab程序?

 

系统变量配置结束。

(3)VS2015环境配置:

1打开VS中得项目工程文件,对项目进行属性设置,在解决方案资源管理器中选中项目,右键选择属性进行项目属性配置。如下图所示。

如何利用GPU(CUDA)加速Matlab程序?

 

2在项目得属性页中对所有配置进行一下操作。首先对VC++ 目录栏中得包含目录及库目录进行配置。在包含目录中添加所安装matlab文件夹中的extern\include和extern\include\win64,在库目录中添加extern\lib\win64\microsoft。如下图所示。(本机matlab安装于D:\matlab文件夹。)

如何利用GPU(CUDA)加速Matlab程序?

 

接着配置链接器,选择常规选项栏中得附加库目录进行编辑。添加所安装的Matlab文件夹中的extern\lib\win64\microsoft.如下图所示。

如何利用GPU(CUDA)加速Matlab程序?

 

最后配置链接器输入选项栏中的附加依赖项。在附加依赖项中添加:libmat.lib
、libmx.lib、libmex.lib、libeng.lib如图所示。

如何利用GPU(CUDA)加速Matlab程序?

 

现VS环境配置结束。

在matlab,VS2015和系统变量成功配置后即可进行matlab与CUDA C的混合编程。

 

  1. matlab中调用.cu程序

在对matlab的配置中安装了mex文件,MEX文件是一种可在matlab环境中调用的C语言(或fortran)衍生程序。

以matlab安装目录下的mexGPUExample.cu文件为例,该文件在所安装的matlab文件夹中的toolbox\distcomp\gpu\extern\src\mex夹内,在matlab中更改路径到相应的位置。如下图所示。

如何利用GPU(CUDA)加速Matlab程序?

 

首先使用mexcuda针对该mexGPUExample.cu文件,生成其mex文件。在命令行输入mexcuda mexGPUExample.cu。如下图所示。

如何利用GPU(CUDA)加速Matlab程序?

 

Mex文件生成成功会有如下显示,并生成相应的mex64文件

如何利用GPU(CUDA)加速Matlab程序?

 

 

MEX文件的调用极为方便,其调用方式与MATALAB的内建函数完全相同,只需要在命令窗口内输入对应的文件名称即可。如下图所示。

如何利用GPU(CUDA)加速Matlab程序?

 

  1. C语言MEX程序代码文件

C语言MEX程序代码文件有计算子例程(Computational routine)和接口子程序(GatWay routine)两个相互独立的子程序组成。其中,计算子例程的功能是完成所需要的计算,它和具有相同功能的一般C源程序文件相同;接口子程序的功能则是计算子程序和MATALAB的接口,用户实现两个不同内存空间中的通信。

接口函数:mexFunction

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])

nlhs:输出参数数目  
plhs:指向输出参数的指针 
nrhs:输入参数数目 

prhs:指向输入参数的指针

  1. 获得输入、输出参数

输入,输出参数的获取可以用两种方式

1读取mat数据文件

将matlab中所需要的数据以mat文件形式保存。如save(‘路径’,’变量名称’)。

之后则可在程序中对该mat文件数据进行读写操作。(注:所读写的文件按每一列依次操作)。

2使用接口函数传递参数

如:[a,b]=test(c,d,e)

c,d,e为3个输入参数,a,b为两个输出参数这里的输入输出参数的指针都是指向mxArray类型。当调用test函数时会将prhs[0]=c ,prhs[1]=d ,prhs[2]=e。在c语言程序中需要使用的是mxArray指针指向的数据。因此在需要对mxArray数据进行转换。mxGetPr函数从指向mxArray类型数据的prhs[0]获得了指向double类型的指针。再通过mxGetM和mxGetN来获得输入参数的行数和列数后即可构造相应的输入矩阵。

a,b为两个输出参数。a=plhs[0], b=plhs[1],因为输出参数的指针为指向mxArray类型,需对该数据构造相应的mxArray。

mxCreateDoubleMatrix(int m, int n, mxComplexity ComplexFlag)函数得到m*n矩阵大小的mxArray的指针,现即可放入plhs[],中传回。对输出参数的赋值与输入参数相同。

 

在完成了以上步骤之后即成功完成了matlab与cuda(c语言)的混合编程。