实战:使用MATLAB进行GPU高级编程


在GPU上执行能够加快我的应用程序吗?

GPU能够对符合以下标准的应用程序进行加速:

大规模并行—计算能够被分割成上百个或上千个独立的工作单元。

计算密集型—计算消耗的时间显著超过了花费转移数据到GPU内存以及从GPU内存转移出数据的时间。

不满足上述标准的应用程序在GPU上运行时可能会比CPU要慢。

使用MATLAB进行GPU编程

FFT,IFFT以及线性代数运算超过了100个内置的MATLAB函数,通过提供一个类型为GPUArray(由并行计算工具箱提供的特殊数组类型)的输入参数,这些函数就能够直接在GPU上运行。这些启用GPU的函数都是重载的,换句话说,这些函数根据传递的参数类型的不同而执行不同的操作。

例如,以下代码使用FFT算法查找CPU上伪随机数向量的离散傅里叶变换:

A = rand(2^16,1);

B = fft (A);

为在GPU上执行相同的操作,我们首先使用gpuArray命令将数据从MATLAB工作空间转移至GPU设备内存。然后我们能够运行重载函数fft:

A = gpuArray(rand(2^16,1));

B = fft (A);

fft操作在GPU上而不是在CPU上执行,因为输入参数(GPUArray)位于GPU的内存中。

结果B存储在GPU当中。然而,B在MATLAB工作空间中依旧可见。通过运行class(B),我们看到B是一个GPUArray。

class(B)

ans =

parallel.gpu.GPUArray

我们能够使用启用GPU的函数继续对B进行操作。例如,为可视化操作结果,plot命令自动处理GPUArrays。

plot(B);

为将数据返回至本地的MATLAB工作集,你可以使用gather命令。例如

C = gather(B);

C现在是MATLAB中的double,能够被处理double变量的所有MATLAB函数操作。

在这个简单的例子当中,执行单个FFT函数节省的时间通常少于将向量从MATLAB工作集移动到设备内存的时间。一般来说是这样的但是也取决于硬件和阵列规模。数据传输开销可能变得异常显著以至于降低了应用的总体性能,尤其是当你重复地在CPU和GPU之间交换数据,执行相对来说很少的计算密集型操作时。更有效率的方式是当数据处于GPU当中时对数据进行一些操作,只在必要的情况下才将数据返回至CPU。

需要指出的是,和CPU类似,GPU的内存也是有限的。然而,与CPU不同,GPU不能在内存和硬盘之间交换数据。因此,你必须核实你希望保留在GPU当中的数据不会超出内存的限制,尤其是当用到大规模矩阵时。通过运行gpuDevice命令,可以查询GPU卡,获取信息比如名称,总内存以及可用内存。

采用MATLAB解波动方程

为将上述例子应用到具体的环境中,我们在一个实际的问题中实现GPU的功能。计算目标是解二阶波动方程。

当u=0时到达临界值。我们使用基于波谱法的算法解空间方程,使用基于二阶中心有限差分法的算法解时间方程。