主要内容

基准测试\ b的GPU

这个例子看我们如何基准的解决线性系统在GPU上。MATLAB®代码来解决xA * x =是非常简单的。最频繁,我们使用矩阵左部,也被称为mldivide或反斜杠符(\)来计算x(即,x = A \ b)。

相关例子:

这个示例中所示的代码可以在这个函数:

函数结果= paralleldemo_gpu_backslash (maxMemory)

重要的是要选择合适的矩阵大小的计算。我们可以通过指定的系统内存GB可用CPU和GPU。默认值是只基于GPU上可用内存的数量,你可以指定一个值,是适合您的系统。

如果输入参数个数= = 0 g = gpuDevice;maxMemory = 0.4 * g.AvailableMemory / 1024 ^ 3;结束

基准测试函数

我们想基准矩阵左部(\),而不是CPU和GPU之间的数据传输,成本所花费的时间创建一个矩阵,或其他参数。因此我们单独解决的数据生成的线性系统,并测量只有时间做后者。

函数[A, b] = getData (n, clz)流(创建一个矩阵的大小% d - % d。\ n”n, n);A =兰德(n, n, clz) + 100 *眼(n, n, clz);b =兰德(n, 1, clz);结束函数时间= timeSolve (A, b, waitFcn)抽搐;x = \ b;% #好< NASGU >我们不需要x的值。waitFcn ();%等待操作完成。时间= toc;结束

选择问题的大小

与许多其他的并行算法,并行求解一个线性系统的性能很大程度上取决于矩阵的大小。在其他的例子,如基准\ b,我们比较不同的矩阵大小的算法的性能。

%宣布矩阵的大小是1024的倍数。maxSizeSingle =地板(√maxMemory * 1024 ^ 3/4));maxSizeDouble =地板(√maxMemory * 1024 ^ 3/8));一步= 1024;如果maxSizeDouble / = > = 10步一步一步*地板(maxSizeDouble /(5 *步骤));结束sizeSingle = 1024:步骤:maxSizeSingle;sizeDouble = 1024:步骤:maxSizeDouble;

比较性能:吉拍

我们用每秒浮点运算的数量作为衡量性能,因为这可以让我们比较不同大小的矩阵的算法的性能。

给定一个矩阵的大小,基准测试函数创建矩阵一个和右边b一次,然后解决一个\ b几次得到一个准确的时间。我们使用的浮点操作数HPC的挑战,这对于一个n×n的矩阵,我们计算浮点运算2/3 * n ^ 3 + 3/2 * n ^ 2

传递函数在处理一个等待的函数。在CPU上,这个功能没有。在GPU,这个函数等待所有等待操作完成。在这种方式可以确保准确的时间。

函数gflops = benchFcn (A, b, waitFcn) numReps = 3;时间=正;%几次我们解决线性系统和计算吉拍%根据最好的时间。itr = 1: numReps tcurr = timeSolve (A, b, waitFcn);时间= min (tcurr、时间);结束%测量引入的开销通过调用等功能。tover =正;itr = 1: numReps抽搐;waitFcn ();tcurr = toc;tover = min (tcurr tover);结束%去除测量时间的开销。不允许时间%变得消极。时间= max(时间- tover, 0);n =大小(1);失败= 2/3 * n ^ 3 + 3/2 * n ^ 2;gflops =失败/时间/ 1 e9;结束%的CPU不需要等待:这个函数处理是一个占位符。函数waitForCpu ()结束%的GPU,以确保准确的时间,我们需要等待设备%所有等待操作完成。函数waitForGpu(设备)等(设备);结束

执行标准

在完成所有的设置,它是简单的执行标准。然而,计算需要花很长时间才能完成,所以我们打印一些中间状态信息完成每个矩阵大小的基准测试。我们还封装了遍历所有的矩阵大小在一个函数中,基准单-和双精度计算。

函数[gflopsCPU, gflopsGPU] = executeBenchmarks (clz、大小)流([与% d % s-precision不同基准的矩阵的大小\ nranging从% d - % d % d % d。\ n”),长度(大小),clz大小(1)、大小(1)、大小(结束),大小(结束));gflopsGPU = 0(大小(尺寸));gflopsCPU = 0(大小(尺寸));gd = gpuDevice;i = 1:长度(大小)n =大小(我);[A, b] = getData (n, clz);gflopsCPU (i) = benchFcn (A, b, @waitForCpu);流(“吉拍CPU: % f \ n”gflopsCPU(我));= gpuArray ();b = gpuArray (b);gflopsGPU (i) = benchFcn (A, b, @ () waitForGpu (gd));流(“对GPU吉拍:% f \ n”gflopsGPU(我));结束结束

然后,我们执行单引号和双精度的基准。

(cpu、gpu) = executeBenchmarks (“单一”,sizeSingle);结果。sizeSingle = sizeSingle;结果。gflopsSingleCPU = cpu;结果。gflopsSingleGPU = gpu;(cpu、gpu) = executeBenchmarks (“双”,sizeDouble);结果。sizeDouble = sizeDouble;结果。gflopsDoubleCPU = cpu;结果。gflopsDoubleGPU = gpu;
与7个不同的单精度基准矩阵的大小从1024 - 19456年- 1024 - 19456。创建一个矩阵的大小1024 - - 1024。吉拍CPU: 43.805496吉拍GPU: 78.474002创建一个矩阵的大小4096 - - 4096。吉拍CPU: 96.459635吉拍GPU: 573.278854创建一个矩阵的大小7168 - - 7168。吉拍CPU: 184.997657吉拍GPU: 862.755636创建一个矩阵的大小10240 - - 10240。吉拍CPU: 204.404384吉拍GPU: 978.362901创建一个矩阵的大小13312 - - 13312。吉拍CPU: 218.773070吉拍GPU: 1107.983667创建一个矩阵的大小16384 - - 16384。吉拍CPU: 233.529176吉拍GPU: 1186.423754创建一个矩阵的大小19456 - - 19456。吉拍对CPU: 241.482550吉拍在GPU上:1199.151846开始基准,5种不同的双精度矩阵的大小从1024 - 13312年- 1024 - 13312。创建一个矩阵的大小1024 - - 1024。 Gigaflops on CPU: 34.902918 Gigaflops on GPU: 72.191488 Creating a matrix of size 4096-by-4096. Gigaflops on CPU: 74.458136 Gigaflops on GPU: 365.339897 Creating a matrix of size 7168-by-7168. Gigaflops on CPU: 93.313782 Gigaflops on GPU: 522.514165 Creating a matrix of size 10240-by-10240. Gigaflops on CPU: 104.219804 Gigaflops on GPU: 628.301313 Creating a matrix of size 13312-by-13312. Gigaflops on CPU: 108.826886 Gigaflops on GPU: 681.881032

绘制的性能

我们现在可以画出结果,CPU和GPU的性能进行比较,对单引号和双精度。

首先,我们看看反斜杠算子的性能在单精度。

无花果=图;ax =轴(“父”图);情节(ax,结果。sizeSingle results.gflopsSingleGPU,“- x”,结果。sizeSingle results.gflopsSingleCPU,“o”网格);传奇(“图形”,“CPU”,“位置”,“西北”);标题(ax,单精度性能的)ylabel (ax,“吉拍”);包含(ax,矩阵大小的);drawnow;

现在,我们看看双精度的反斜杠算子的性能。

无花果=图;ax =轴(“父”图);情节(ax,结果。sizeDouble results.gflopsDoubleGPU,“- x”,结果。sizeDouble results.gflopsDoubleCPU,“o”)传说(“图形”,“CPU”,“位置”,“西北”);网格;标题(ax,“双精度性能”)ylabel (ax,“吉拍”);包含(ax,矩阵大小的);drawnow;

最后,我们看看加速时反斜杠符比较GPU和CPU。

speedupDouble = results.gflopsDoubleGPU. / results.gflopsDoubleCPU;speedupSingle = results.gflopsSingleGPU. / results.gflopsSingleCPU;无花果=图;ax =轴(“父”图);情节(ax,结果。sizeSingle speedupSingle,“v”,结果。sizeDouble speedupDouble,“- *”网格);传奇(单精度的,“双精度”,“位置”,“东南”);标题(ax,计算在GPU与CPU的加速);ylabel (ax,“加速”);包含(ax,矩阵大小的);drawnow;

结束
ans = sizeSingle:(1024 4096 7168 10240 13312 16384 19456] gflopsSingleCPU: [1 x7双]gflopsSingleGPU: [1 x7双]sizeDouble: [1024 4096 7168 10240 13312] gflopsDoubleCPU: [34.9029 74.4581 93.3138 104.2198 108.8269] gflopsDoubleGPU: (72.1915 365.3399 - 522.5142 628.3013 - 681.8810)