在matlab中使用GPU加速,来加速矩阵运算。
首先如前面所说,并不是所有GPU都能在maltab中进行加速的,貌似只有NVDIA的显卡可以吧。
硬件:GeForce GTX 980
软件:Matlab 2015a (Matlab 2012以后的版本才带有GPU加速的工具箱)
下面开始介绍怎么玩GPU加速
第一步:在matlab命令窗口,运行gpuDevice,查看自己的显卡是否具备GPU加速功能
gpuDevice
正常情况下matlab会输出如下结果代表具备GPU加速功能:
CUDADevice with properties: Name: \'GeForce GTX 980\' Index: 1 ComputeCapability: \'5.2\' SupportsDouble: 1 DriverVersion: 7.5000 ToolkitVersion: 6.5000 MaxThreadsPerBlock: 1024 MaxShmemPerBlock: 49152 MaxThreadBlockSize: [1024 1024 64] MaxGridSize: [2.1475e+09 65535 65535] SIMDWidth: 32 TotalMemory: 4.2950e+09 AvailableMemory: 3.3203e+09 MultiprocessorCount: 16 ClockRateKHz: 1380000 ComputeMode: \'Default\' GPUOverlapsTransfers: 1 KernelExecutionTimeout: 1 CanMapHostMemory: 1 DeviceSupported: 1 DeviceSelected: 1
第二步:CPU和GPU之间的数据交换,大致有如下几个函数和功能:
(1)、将数据从CPU中搬入GPU,函数:gpuArray,用法 M = gpuArray(M);
(2)、在GPU中计算完成后,将数据搬出到CPU存储,函数:gather,用法M=gather(M)。
下面给大家看看最简单的用法以及处理同样矩阵运算时的时间对比:
clear all clc M = rand(2000,2000); % 生成一个随机矩阵 tic [A1,B1] = eig(M); % 求该随机矩阵的特征值和特征向量 t1=toc tic M = gpuArray(M); % 将数据从CPU中搬到GPU [A2,B2] = eig(M); % 求特征值和特征向量 A2 = gather(A2); % 将数据从GPU中搬到CPU t2 = toc
输出结果(运行时间对比):
t1 = 14.1483 t2 = 9.1567
总结:虽然加速不是特别明显,不过还是非常给力的,需要说明的是,一般的GPU对于单精度型的数据运算加速更明显一点,因此我们在编写代码时,最好能够将数据从double型转换为single型,即M=single(M),然后在使用M=gpuArray(M),将数据搬迁到GPU进行计算,下面看看转换为单精度型后的时间对比:
clear all clc M = rand(2000,2000); % 生成一个随机矩阵 tic [A1,B1] = eig(M); % 求该随机矩阵的特征值和特征向量 t1=toc tic M = single(M); % 将数据转换为单精度型 M = gpuArray(M); % 将数据从CPU中搬到GPU [A2,B2] = eig(M); % 求特征值和特征向量 A2 = gather(A2); % 将数据从GPU中搬到CPU t2 = toc
运行结果:
t1 = 14.8332 t2 = 5.0963
GPU对eig和svd进行加速,和cpu运行时间对比
clear all A = rand(2000,2000); tic A1 = gpuArray(single(A)); [U,S,V] = svd(A1,\'econ\'); A2 = U*S*V\'; A3 = gather(A2); t = toc tic [U1,S1,V1] = svd(A,\'econ\'); A4 = U1*S1*V1\'; t2 = toc error = norm(A3-A4,\'fro\') tic A1 = gpuArray(single(A)); [vv,dd] = eig(A1); t3 = toc
结果:
t = 3.1564 t2 = 7.1644 error = 0.0032 t3 = 5.2244 t4 = 17.6389
是不是加速更明显了呢?
注:1、单精度型初始化矩阵函数例:X=rand(10,\'single\'); %定义在CPU上的一个10x10的随机初始化数组
2、直接在GPU中初始化矩阵例:GX=rand(10,\'gpuArray\'); %直接在GPU设备上随机初始化一个10x10的数组
3、判断数据DATA是否存在于GPU内存中例:TF=existOnGPU(DATA)
4、计算效率统计例:t=gputimeit(F,N) %返回执行F操作N次所需的时间,当N=1时可以缺省