文档

在GPU上对A\b进行基准测试

这个例子看我们如何才能基准的GPU线性系统的求解。该MATLAB®代码来解决xA * x =很简单。最常见的是,我们使用矩阵左除,也被称为mldivide或反斜杠操作符(\),以计算x(即,x = A \ b)。

相关例子:

这个例子中的代码可以在这个函数中找到:

功能结果= paralleldemo_gpu_backslash(maxMemory)

为计算选择合适的矩阵大小是很重要的。我们可以通过指定CPU和GPU可用的系统内存量(以GB为单位)来实现这一点。默认值仅基于GPU上可用的内存量,你可以指定一个适合你系统的值。

如果nargin == 0 g = gpuDevice;maxMemory = 0.4 * g.AvailableMemory / 1024 ^ 3;结束

该基准测试功能

我们想要基准矩阵左除法(\),而不是在CPU和GPU之间传输数据的成本,它需要创建一个矩阵的时间,或其他参数。因此,我们将数据生成与线性系统的求解分离开来,只测量后者所需的时间。

功能[A,B] =的getData(N,CLZ)fprintf中(“创建大小%d逐%d的矩阵。\ N”n, n);A = rand(n, n, clz) + 100*eye(n, n, clz);b = rand(n, 1, clz);结束功能time = time olve(A, b, waitFcn) tic;x = \ b;%#OK 我们不需要x的值。waitFcn ();等待操作完成。时间= TOC;结束

选择问题大小

与许多其他并行算法一样,并行求解线性系统的性能在很大程度上取决于矩阵的大小。如在其他示例中所见,例如基准A \ B,我们比较算法对不同矩阵大小的性能。

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

比较性能:吉拍

我们使用浮点运算每秒作为我们的性能指标,因为这使我们能够比较算法对不同矩阵大小的性能的数量。

给定矩阵大小,基准测试函数创建矩阵一个而右边b一次,然后解决了A \ B几次才能得到准确的时间。我们在HPC挑战中使用浮点运算计数,因此对于一个n×n矩阵,我们将浮点运算计数为三分之二* N ^ 3 + 3/2 * N ^ 2

该功能是在手柄传递到“等待”的功能。在CPU,这个函数什么也不做。在GPU中,该功能会等待所有未决操作完成。以这种方式等待确保精确的时序。

功能GFLOPS = benchFcn(A,B,waitFcn)numReps = 3;时间= INF;%我们对这个线性系统解了几次,计算了千兆次浮点运算基于最好的时间。ITR = 1:numReps tcurr = timeSolve(A,B,waitFcn);时间=分钟(tcurr,时间);结束%度量调用等待函数所引入的开销。TOVER = INF;1:numReps tic;waitFcn ();tcurr = toc;(tcurr, tover);结束%从测量时间中删除开销。不要让时间去做%变为负值。时间= max(时间转换,0);n = size(A, 1);2/3*n^3 + 3/2*n^2;gflops =失败/时间/ 1 e9;结束% CPU不需要等待:这个函数句柄是一个占位符。功能waitForCpu ()结束对GPU,为了确保准确的计时,我们需要等待设备完成所有挂起的操作。功能waitForGpu(设备)等(设备);结束

执行标准

做完所有的设置功能,可以直接执行基准。然而,计算可能需要较长时间才能完成,所以我们打印一些中间状态的信息,因为我们完成每个矩阵大小的标杆。我们也概括了所有的矩阵大小循环的功能,以基准单,双精度计算。

功能[gflopsCPU, gflopsGPU] = executebenchmark (clz, size)'以%d不同的%s精度开始基准测试''尺寸的矩阵\来自%nranging d逐%d到%d逐%d \ N']长度(尺寸),clz,尺寸(1),尺寸(1),尺寸(结束),大小(结束));gflopsGPU = 0(大小(尺寸));gflopsCPU = 0(大小(尺寸));gd = gpuDevice;I = 1:长度(大小)N =尺寸(I);[A,B] =的getData(N,CLZ);gflopsCPU(1)= 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);results.sizeSingle = sizeSingle;results.gflopsSingleCPU = CPU;results.gflopsSingleGPU = GPU;[CPU,GPU] = executeBenchmarks(“双”, sizeDouble);结果。sizeDouble = sizeDouble;结果。gflopsDoubleCPU = cpu;结果。gflopsDoubleGPU = gpu;
开始基准与尺寸范围从1024通过-1024至19456逐19456的7种不同的单精度矩阵。创建大小为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与尺寸范围从1024通过-1024至13312逐13312的5个不同的双精度矩阵开始基准。创建大小为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 =轴(“父”图);图(斧,results.sizeSingle,results.gflopsSingleGPU,“- x”,结果。sizeSingle results.gflopsSingleCPU,“o”)网格;传说('GPU',“CPU”,“位置”,“西北”);标题(ax,单精度性能的) ylabel (ax,“亿次”);xlabel(斧,矩阵大小的);drawnow;

现在,我们来看看双精度反斜杠操作符的性能。

无花果=图。AX =轴(“父”图);情节(ax,结果。sizeDouble results.gflopsDoubleGPU,“- x”,results.sizeDouble,results.gflopsDoubleCPU,“o”)传说('GPU',“CPU”,“位置”,“西北”);网格;标题(ax,“双精度性能”) ylabel (ax,“亿次”);xlabel(斧,矩阵大小的);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,'加速');xlabel(斧,矩阵大小的);drawnow;

结束
ANS = sizeSingle:[1024 4096 7168 10240 13312 16384 19456] gflopsSingleCPU:[1X7双] gflopsSingleGPU:[1X7双] 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.3013681.8810]
是这个主题有帮助吗?