在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来优化您的应用程序以获得最佳性能。

本文演示Parallel Computing Toolbox中的功能让你能够运行MATLAB®代码在GPU上通过制作一些简单的改变你的代码。我们举例说明通过解决在使用谱方法二阶波动方程这种方法。

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

波动方程广泛应用于工程学科,包括地震学、流体动力学、声学和电磁学,用来描述声、光和流体波。

一个使用光谱方法来求解波动方程的算法是并行化的一个好候选,因为它满足使用GPU加速的两个标准(见“在GPU上执行会加速我的应用程序吗?”):

它是计算密集型的。该算法执行许多快速傅立叶变换(FFT)和逆快速傅立叶变换(的IFFT)。确切数量取决于网格的尺寸(图2)和包括在仿真时间的步数。每个时间段需要两个FFT和不同的基质4点的IFFT,单个计算可能涉及数以十万计的时间步长。

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

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

在GPU上执行会加速我的应用程序吗?

GPU可以加速一个应用程序,如果它符合以下两个条件:

计算密集型-花费在计算上的时间大大超过了在GPU内存之间传输数据所花费的时间。

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

不满足这些条件的应用程序实际上可能在GPU上比在CPU上运行得更慢。

MATLAB中的GPU计算

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

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

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

一个=兰德(2 ^ 16,1);

B = fft (A);

要在GPU上执行相同的操作,我们先用gpuArray命令将数据从MATLAB工作区传输到设备内存。然后我们就可以跑了FFT,这是对数据重载功能之一:

A = gpuArray(RAND(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的一样,具有有限的回忆。然而,不同于CPU的,他们没有能力来交换内存和磁盘。因此,你必须确认你想保持在GPU上不超过其内存限制,尤其是当您正在使用大型矩阵处理的数据。通过运行gpuDevice,您可以查询您的GPU卡,获取诸如名称、总内存和可用内存等信息。

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

为了把上面的例子中的来龙去脉,让我们实现一个真正的问题的GPU功能。我们计算的目标是解决二阶波动方程

\ [\压裂{\局部^ 2 U} {\局部吨^ 2} = \压裂{\局部^ 2 U} {\部分的x ^ 2} + \压裂{\局部^ 2 U} {\部分Y 12} \]

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

谱法是求解偏微分方程的常用方法。用谱方法,解被近似成连续基函数的线性组合,如正弦和余弦。在这种情况下,我们应用契比雪夫谱方法,它使用契比雪夫多项式作为基函数。

在每个时间步长,计算在使用切比雪夫谱方法两者\(X \)和\(Y \)尺寸当前解决方案的二阶导数。与旧的溶液和当前解决方案使用这些衍生物一起,我们应用二阶中心差分法(也被称为跨越式方法)来计算新的解决方案。我们选择一个时间步长维持这种跨越式方法的稳定性。

在MATLAB算法是计算密集型的,并且在上方我们计算解决方案发展的网格元素的数量,时间的算法将大幅增加执行。当使用2048×2048网格单个CPU上执行,这需要超过一分钟即可完成仅有50个时间步。请注意,这时候已经包括MATLAB固有的多线程的性能优势。自R2007a,MATLAB支持多种功能的万博1manbetx多线程计算。这些功能在多个线程自动执行,而无需显式指定命令在代码中创建线程。

在考虑如何使用加速并行计算工具箱这个计算,我们将专注于代码进行计算,每次一步。图3显示了获得在GPU上运行的算法所需的变化。请注意,计算包括MATLAB操作的,这使GPU超载功能都可以通过并行计算工具箱。这些操作包括FFT和IFFT,矩阵乘法,以及各种元件为单位的运算。其结果是,我们并不需要改变算法以任何方式来执行它在GPU上。我们简单地使用数据转移到GPUgpuArray在进入每个时间步骤计算结果的循环之前。

图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上执行。

比较CPU和GPU的执行速度

为了评价使用GPU来解决二次波方程的益处,我们运行中,我们测量的时间的算法把执行用于64个网格大小50的时间步长,128,512,1024的量的基准研究,并2048在Intel®至强®处理器为X5650,然后使用NVIDIA®特斯拉C2050 GPU。

对于2048的网格大小,算法显示计算时间从CPU上的1分钟减少到GPU上的不到10秒,减少了7.5倍(图4)。对数尺度图显示,对于较小的网格大小,CPU实际上更快。然而,随着技术的发展和成熟,GPU解决方案越来越能够处理更小的问题,我们预计这一趋势将继续下去。万博 尤文图斯

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

先进的GPU与MATLAB编程

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

要加快多简单的操作,在GPU上的算法,可以使用arrayfun,它将函数应用于数组的每个元素。因为arrayfun是启用了GPU的功能,你只在对单一调用的开销招致内存传输arrayfun,而不是在每个单独的操作。

最后,谁写自己的CUDA代码可以使用CUDAKernel接口Parallel Computing Toolbox中有经验的程序员来整合这个代码与MATLAB。所述CUDAKernel接口使甚至更细粒度的控制,以加快其分别为性能瓶颈的代码部分。它创建了一个MATLAB对象,提供了访问编译成PTX代码现有内核(PTX是一种低层次的并行线程执行的指令集)。然后,您调用feval命令,以评估在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计算技术®它由并行计算架构、开发工具、库和用于GPU计算的编程指令组成。

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

主办。该CPU和系统内存。

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

出版2011 - 91967v01


参考

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

  2. 见第6章(内存优化)的NVIDIA“CUDA C最佳实践”的有关通过最小化数据传输提高了性能的进一步信息的文档。