在GPU上运行MATLAB程序

matlab在运行一些大型程序时会比较慢,如果你的电脑正好有一张不错的显卡,那么为什么不用显卡来加速matlab运行呢?

本文将讲解如何使用gpu来加速matlab运行程序,并总结适合gpu加速的matlab程序。

准备工作:电脑上要有显卡,显卡要有cuda core。

目录

1. 认识你电脑的GPU

2. 内存数据搬运

3. GPU加速举例

4. GPU加速方法

5. 适合GPU加速的程序


1. 认识你电脑的GPU

MATLAB指令为:gpuDevice

下面是我电脑上的gpu设备信息

>> gpuDevice

ans = 

  CUDADevice - 属性:

                      Name: 'NVIDIA RTX A2000 12GB'
                     Index: 1
         ComputeCapability: '8.6'
            SupportsDouble: 1
             DriverVersion: 11.5000
            ToolkitVersion: 11
        MaxThreadsPerBlock: 1024
          MaxShmemPerBlock: 49152
        MaxThreadBlockSize: [1024 1024 64]
               MaxGridSize: [2.1475e+09 65535 65535]
                 SIMDWidth: 32
               TotalMemory: 1.2878e+10
           AvailableMemory: 1.1272e+10
       MultiprocessorCount: 26
              ClockRateKHz: 1200000
               ComputeMode: 'Default'
      GPUOverlapsTransfers: 1
    KernelExecutionTimeout: 1
          CanMapHostMemory: 1
           DeviceSupported: 1
           DeviceAvailable: 1
            DeviceSelected: 1

说明一下打印出来的信息的含义:

参数含义说明
Compute Capability计算能力

NVIDIA GPU Compute Capability解释_Forskamse的博客-CSDN博客

决定了GPU的通用规格和可用特性。Compute Capability的数值和GPU的计算速度无关,但是和GPU可执行的任务种类有关。

小数点前的第一位表示设备核心架构,小数点后的一位表示更加细微的进步,包括对核心架构的改进和功能的完善。

SupportsDouble是否支持双精度浮点运算1表示支持
 MaxThreadsPerBlock每个block中可开的最大线程数量
MaxShmemPerBlock每个Block可用的最大共享内存大小
MaxThreadBlockSize三个维度各自最大的线程数量
MaxGridSize三个维度各自最大的Grid数量
SIMDWidth同一条指令多个数据位宽同时执行的线程数?
MultiprocessorCountstreaming multiprocessors 数量
ComputeMode模式default表示该设备不受限制,多个应用程序可以同时使用它。MATLAB 可以与其他应用程序(包括其他 MATLAB 会话或工作线程)共享设备。
GPUOverlapsTransfers是否支持覆盖传输
KernelExecutionTimeout

长时间运行的内核的超时标志

CanMapHostMemory支持将主机内存映射到 CUDA 地址空间
DeviceSupported本机Matlab支持的GPU设备数
DeviceAvailable指示设备是否可用于当前 MATLAB 会话
DeviceSelected当前选定设备的标志

 附上一张GPU的架构图,便于理解

如果你能扫描出类似上面的结果,那么你就可以用gpu加速matlab程序啦。

2. 内存数据搬运

在正式开始加速之前,你还得明白一点,那就是数据的搬运。

如上图所示,正常来讲,matlab运行中的数据都是在内存里的,也就是电脑CPU的内存

如果要用GPU做计算,首先数据得在GPU的显存上

这就要研究下数据的搬运了:

GPU与显存位于显卡上,CPU位于电脑主板上,CPU与GPU之间通过PCIe连接

虽然PCIe已经是目前最快的接口了,但是毕竟是有速度上限的,所以当数据量多了以后必然传输数据是要时间的,这也是做加速必须要考虑的一个问题:

加速省下的时间能不能大于数传消耗的时间?

3. GPU加速举例

话不多说,直接上代码:

M = single(rand(7000,7000));            % 生成一个随机矩阵
tic
[A1,B1] = eig(M);               % 求该随机矩阵的特征值和特征向量
t_cpu = toc


M = gpuArray(M);                % 将数据从CPU中搬到GPU
tic
[A2,B2] = eig(M);               % 求特征值和特征向量
t_gpu = toc
% A2 = gather(A2);                % 将数据从GPU中搬到CPU
% B2 = gather(B2); 

求一个较大矩阵的特征值和特征向量,分别运行在CPU和GPU上,并统计结果

怎么证明上面这段代码分别跑在了CPU和GPU上呢?很简单,打开任务管理器(win11):

点击任务管理器的性能标签栏,可以直观的看到CPU和GPU的利用率,CPU和GPU的利用率都依次跑到过100%

我们看看matlab打印的结果是不是gpu的时间比较短,下面是我电脑运行的结果,大家根据自己的电脑的性能适当的调节矩阵的大小。

可以看到GPU运行的速度是CPU的1.6倍。

再看一下matlab的工作区:

我们发现矩阵A2、B2、M的类型是gpuArray,代码中也调用了gpuArray()函数

所以GPU加速的关键就在于gpuArray

4. GPU加速方法

gpuArray是matlab自带的api函数,下面给出matlab官方的帮助文档:

Array stored on GPU - MATLAB - MathWorks 中国

这里总结几个常用的方法:

方法1:搬运数据  M2 = gpuArray(M1); 

如第3节所示,讲位于内存的矩阵M1搬移到位于显存的矩阵M2

方法2:直接声明位于显存的数据  rand(7000,7000,'gpuArray');

支持这样直接创建gpuArray阵列的函数有300多个,若要查看,输入命令:methods('gpuArray')

方法3:让函数运行在GPU上  [A2,B2] = arrayfun(@eig,M); 

arrayfun的加速效果没有前面两个好,gpu没有完全被调起来

另外与gpu有关的api函数还有一些:

函数

功能

gpuArray

在GPU上创建阵列。

gather

把分布式阵列或gpuArray转移到Matlab的workspace。

existsOnGPU

确定gpuArray或CUDAKernel在GPU上可用。

gpuDevice

查询或选择GPU设备。

gpuDeviceCount

目前GPU的设备数量。

gputimeit

在GPU上运行函数所需时间。

reset

重置GPU设备并清空它的内存。

wait(GPUDevice)

等待GPU计算完成。

arrayfun

对GPU阵列上的每个元素应用函数。

bsxfun

用于GPU阵列的二元但扩展函数。

pagefun

对GPU阵列的每一页应用函数。

parallel.gpu.CUDAKernel

从PTX和CU代码创建 GPU CUDA kernel 对象。

feval

评估GPU的核。

setConstantMemory

设置GPU的一些常量内存。

mxInitGPU

这是一个C语言函数,在当前选择的设备上初始化Matlab GPU计算库。

可自行查阅matlab的帮助文档。

5. 适合GPU加速的程序

适合GPU加速的程序具有以下几个特点:

数据类型不是double。如果把第3节的代码的数据类型改为默认的double,gpu的加速效果就很一般了,我的机器上如果不转化float,cpu反而比gpu还要快(细心的读者可能注意到我任务管理器cpu的主频有4.5GHz,皮)

高度并行的。各个数据之间运算互不影响,耦合度较低。由于GPU本身硬件基础决定,各个workgroup之间并不相互通信,只有同一workgroup内的work-item之间才相互通信,所以GPU本身并不支持迭代等数据耦合度较高的计算,这是GPU本身要求。

数据量大的。用大量数据或者用同一数据多次调用同一公式或者计算过程,公式本身并不复杂,只是执行的次数较多。

接口交互少的。任务可以分为计算密集型和IO密集型。GPU适合计算密集型,即少量的IO读取+大量的计算;而IO密集型,是指多次使用IO读取+少量计算,这种情况涉及到内存与设显存之间的通信问题,主要限制原因是显存带宽问题。

可多个阶段执行的。运算程序可分解为多个小程序或者同一程序可分多个阶段执行,这就类似于使用集群处理同一任务,将其分解为多个任务碎片分发到各节点执行,以提高运算速率。

  • 17
    点赞
  • 133
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lightninghenry

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值