MATLAB中的GPU编程

由Jill里斯,MathWorks公司和萨拉Zaranek,MathWorks公司


多核机器和超线程技术使科学家,工程师和财务分析师,加快各学科的计算密集型应用。今天,另一种类型的硬件的许诺更高计算性能:图形处理单元(GPU)。

gpu最初用于加速图形渲染,现在越来越多地应用于科学计算。与只包含几个核心的传统CPU不同,GPU拥有大量的整数和浮点处理器并行阵列,以及专用的高速内存。一个典型的GPU由数百个这样的小处理器组成(图1)。

图1所示。比较CPU系统和GPU的核数。

大大增加了吞吐量由GPU成为可能,但是,是有代价的。首先,内存访问成为你的计算一个更可能的瓶颈。数据必须从CPU发送到GPU计算之前,然后再把它从检索。由于GPU连接到通过PCI Express总线主机CPU,存储器访问是比传统CPU慢。1这意味着您的总体计算加速受到算法中发生的数据传输量的限制。其次,用C或Fortran编程gpu需要不同的心智模型和技能集,这可能是困难和耗时的。此外,您必须花时间为特定的GPU微调代码,以优化应用程序的峰值性能。

本文演示了并行计算工具箱中的特性这使您可以运行Matlab®通过对你的代码做一些简单的更改来在GPU上编写代码。我们用谱方法求解一个二阶波动方程来说明这种方法。

为什么要并行化波动方程求解器?

波浪方程在广泛的工程学科中使用,包括地震,流体动力学,声学和电磁学,以描述声音,光线和流体波。

一种使用谱方法来解决波动方程的算法是一个很好的并行化候选者,因为它符合使用GPU的加速标准(请参阅“将在GPU上执行我的应用程序?”):

它是计算密集型的。该算法执行了许多快速傅里叶变换(fft)和反快速傅里叶变换(ifft)。确切的数字取决于网格的大小(图2)和模拟中包含的时间步长的数量。在不同的矩阵上,每个时间步长需要两个fft和四个ifft,单个计算可能涉及几十万个时间步长。

这是大规模并行。并行FFT算法被设计为“分而治之”,从而在不同的数据上重复执行类似的任务。此外,该算法需要处理线程之间的大量通信和足够的内存带宽。IFFT可以类似地并行运行。

图2.在32×32网格上的二次波方程的溶液。

将在GPU上执行加速我的申请吗?

如果拟合以下标准,GPU可以加速应用程序:

计算密集- 在计算上花费的时间显着超过了将数据传输到GPU存储器的时间。

大规模并行-计算可以分解成数百或数千个独立的工作单元。

不满足这些标准的应用程序实际上可能在GPU上运行较慢,而不是CPU。

GPU计算在Matlab中

与波动方程例如在继续之前,我们先回顾MATLAB如何与GPU。

FFT,IFFT,和线性代数运算超过100内置的可通过提供的类型GPUArray,通过并行计算工具箱提供的特殊数组类型的输入参数直接执行在GPU上的MATLAB函数中。这些启用GPU-功能过载换句话说,它们的操作方式取决于传递给它们的参数的数据类型。

例如,下面的代码使用FFT算法在CPU上求一个伪随机数向量的离散傅里叶变换:

a = rand(2 ^ 16,1);

b = fft(a);

要在GPU上执行相同的操作,我们先用GPUArray.命令将数据从MATLAB工作区传输到设备内存。然后我们可以跑fft,这是该数据上的重载函数之一:

= gpuArray(兰德(2 ^ 16,1));

b = fft(a);

fft操作保持在GPU在GPU上,而不是因为它的输入(一个GPUArray)CPU执行。

结果B存储在GPU上。然而,它在MATLAB工作空间中仍然可见。通过运行班级(b),我们可以看到它是一个gpuarray。

班级(b)

ans =.

parallel.gpu.GPUArray

我们可以使用启用GPU的函数继续操纵设备上的B.例如,要想象我们的结果,是阴谋命令将自动适用于GPUArrays:

积(B);

要将数据返回到本地MATLAB工作区,可以使用收集命令;例如

C =收集(B);

C现在是MATLAB中的一个双精度对象,可以由任何处理双精度对象的MATLAB函数进行操作。

在这个简单的例子中,通过执行单个FFT函数保存的时间通常小于将来自MATLAB工作区传输到设备存储器的时间的时间。这通常是真实的,但取决于您的硬件和阵列的大小。数据传输开销可能会变得如此重要的是,它会降低应用程序的整体性能,特别是如果在CPU和GPU之间重复交换数据以执行相对较少的计算密集型操作。在GPU上时,在数据上执行多个操作更有效,仅在需要时将数据带回CPU2

请注意,与cpu一样,gpu也有有限的内存。但是,与cpu不同的是,它们不具备与磁盘交换内存的能力。因此,您必须验证您想要保存在GPU上的数据不会超过其内存限制,特别是在处理大型矩阵时。通过运行GPudevice.,您可以查询GPU卡,获取名称,总内存和可用内存等信息。

实施和加快算法的MATLAB求解波动方程

为了把上面的例子放到上下文中,让我们在一个真实的问题上实现GPU功能。我们的计算目标是解二阶波动方程

\[\压裂{\部分^ 2 u}{\部分t ^ 2} = \压裂{\部分^ 2 u}{\部分x ^ 2} + \压裂{\部分^ 2 u}{\偏y ^ 2} \]

与上边界条件\(U = 0 \)。我们使用基于频谱的方法的算法来解决在空间中的方程和一个二阶中心有限差分法求解方程式中的时间。

谱方法通常用于求解部分微分方程。利用光谱方法,该解决方案近似为连续基函数的线性组合,例如凸片和余弦。在这种情况下,我们应用了Chebyshev光谱法,该方法使用Chebyshev多项式作为基本函数。

在每一个时间步,我们用切比雪夫谱方法计算当前解在\(x\)和\(y\)维上的二阶导数。利用这些导数与旧解和当前解结合,采用二阶中心差分法(又称跳蛙法)计算新解。我们选择一个时间步长来保持这种跳变方法的稳定性。

MATLAB算法是计算密集型的,当我们计算解决方案的网格中的元素数量增加时,算法执行所需的时间就会显著增加。当使用2048 x 2048网格在单个CPU上执行时,仅完成50个时间步骤就需要1分钟以上的时间。注意,这一次已经包含了MATLAB中固有的多线程的性能优势。从R2007a开始,MATLAB支持多个函金宝app数的多线程计算。这些函数自动在多个线程上执行,而不需要显式地指定命令来在代码中创建线程。

在考虑如何使用并行计算工具箱加速此计算时,我们将重点关注为每个时间步骤执行计算的代码。图3说明了让算法在GPU上运行所需的更改。注意,计算涉及MATLAB操作,gpu支持的重载函数可通过并行计算工具箱获得。这些操作包括FFT和IFFT、矩阵乘法和各种元素操作。因此,我们不需要以任何方式改变算法来在GPU上执行它。我们简单地将数据传输到GPU使用GPUArray.在进入计算每个时间步骤的循环之前。

图3.代码比较工具显示CPU和GPU版本的差异。GPU和CPU版本共享超过84%的代码(111条中有94行)。

该计算是在GPU上执行后,我们从GPU到CPU转移的结果。通过启用GPU函数中引用的每个变量必须在GPU上创建或在使用前转移到GPU。

为了将用于光谱微分的权重转换为GPUArray变量,我们使用

W1T = gpuArray(W1T);

某些类型的阵列可以直接构造在GPU上没有我们具有将它们从工作区MATLAB转移。例如,直接在GPU创建零矩阵,我们使用

UXX = parallel.gpu.GPUArray.zeros(N + 1,N + 1);

我们使用收集功能从GPU带回数据;例如:

vvg =聚集(vv);

请注意,GPU的单一数据传输到GPU,然后从GPU进行单一数据传输。每个时间步骤的所有计算都在GPU上执行。

比较CPU和GPU执行速度

为了评估使用GPU解决二阶波方程的好处,我们进行了一项基准研究,其中我们测量了在Intel上执行网格大小为64、128、512、1024和2048的50个时间步所花费的时间®Xeon.®处理器x5650然后使用nvidia®特斯拉C2050 GPU。

对于2048的网格尺寸,该算法在CPU上从超过一分钟的计算时间减少了7.5倍,在GPU上少于10秒(图4)。日志比例绘图显示CPU实际上更快地用于小网格尺寸。然而,随着技术的发展和成熟,GPU解决方案越来越能够处理较小的问题,这是我们期望继续的趋势。金宝搏官方网站

以完成不同栅格尺寸50的时间步图4的基准测试结果示出了时间的剧情需要,使用一个线性标尺(左)或对数标度(右)。

先进的GPU与MATLAB编程

并行计算工具箱提供了一种简单的方法,通过执行它在GPU上以加快MATLAB代码。您只需改变一个函数的输入的数据类型采取已重载GPUArrays许多MATLAB命令的优势。(一个完整的目录内置MATLAB函数支持GPUArray可在金宝app并行计算工具箱文档.)

要加快多简单的操作,在GPU上的算法,可以使用Arrayfun.,它将函数应用于数组的每个元素。因为Arrayfun.是一个启用了gpu的功能,您只在单个调用Arrayfun.,而不是在每个单独的操作。

最后,谁写自己的CUDA代码可以使用CUDAKernel接口Parallel Computing Toolbox中有经验的程序员来整合这个代码与MATLAB。所述CUDAKernel接口使甚至更细粒度的控制,以加快其分别为性能瓶颈的代码部分。它创建了一个MATLAB对象,提供了访问编译成PTX代码现有内核(PTX是一种低层次的并行线程执行的指令集)。然后,您调用函数宏指令命令在GPU上评估内核,使用MATLAB数组作为输入和输出。

总结

工程师和科学家成功地使用了GPU技术,该技术原本是为了加速图形渲染,以加速他们的学科特定的计算。只需最少的努力和不需要广泛的gpu知识,您就可以在MATLAB中使用gpu的强大功能。GPUArrays和支持gpu的MATLAB函数帮助您在不使用低级CUDA编程的情况下加快MATLAB操作。如果您已经熟悉gpu编程,那么MATLAB还允许您将现有的CUDA内核集成到MATLAB应用程序中,而不需要任何额外的C编程。

为了实现GPU的速度,您的应用程序必须满足一些标准,其中包括在CPU和GPU之间发送数据的事实必须比通过GPU运行所获得的性能更少。如果您的应用程序满足这些标准,它是Matlab可用的GPU功能范围的良好候选者。

GPU术语表

CPU(中央处理单元)。计算机中负责计算和控制或监督计算机其他部分的中央部件。CPU对保存在计算机内存中的数据执行逻辑和浮点运算。

GPU(图形处理单元)。最初用于图形渲染的可编程芯片。GPU的高度并行结构使其在并行处理大块数据的算法上比通用cpu更有效。

核心。CPU或GPU芯片内的单个独立的计算单元。CPU和GPU内核并不等同于彼此;GPU内核执行专业的操作而CPU核心是为通用计划

CUDA.®NVIDIA的并行计算技术®由PPU计算的并行计算体系结构和开发人员工具,库和编程指令组成。

设备。包含GPU及其相关内存的硬件卡。

主持人。该CPU和系统内存。

核心。编写用于在GPU上执行的代码。内核是可以在大量线程上运行的函数。并行性来自每个线程,在不同数据上独立地运行相同的程序。

发布2011年 - 91967V01

参考文献

  1. 见第6章(内存优化)的NVIDIA“CUDA C最佳实践”的有关潜在GPU计算瓶颈和GPU的存储器存取最佳化的进一步信息的文档。

  2. 请参阅NVIDIA“CUDA C最佳实践”文档的第6章(内存优化),了解更多关于通过最小化数据传输来提高性能的信息。