主要内容

基准\ b

这个例子展示了如何基准解决线性系统集群上。MATLAB®代码来解决xA * x =是非常简单的。最频繁,使用矩阵左部,也称为mldivide或反斜杠符(\)来计算x(即,x = A \ b)。基准测试的性能矩阵左部门集群上,然而,并不简单。

基准测试的最具挑战性的方面之一是避免落入的陷阱寻找一个数字,代表了系统的整体性能。我们将看看性能曲线,可以帮助您识别您的集群的性能瓶颈,甚至帮助你了解如何基准代码和结果可以得出有意义的结论。

相关例子:

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

函数结果= paralleldemo_backslash_bench (memoryPerWorker)

是非常重要的,选择合适的矩阵大小的集群。我们可以通过指定的系统内存GB可用每个工人这个例子函数作为输入。默认值是非常保守的;你应该指定一个值,是适合您的系统。

如果输入参数个数= = 0 memoryPerWorker = 8.00;%在GB%的警告(“pctexample: backslashbench: BackslashBenchUsingDefaultMemory”,…%(每个工人的可用的系统内存数量”,…%的未指定。使用保守的默认值”,…%的%。2 f (g /工人。'],memoryPerWorker);结束

避免开销

得到一个精确的衡量我们的能力来解决线性系统,我们需要移除任何可能的来源的开销。这包括了当前并行池和暂时禁用死锁检测功能。

p =质量;如果isempty (p)错误(“pctexample: backslashbench: poolClosed”,(这个例子需要并行池。”“手动启动一个池使用parpool命令或一组的“你平行偏好自动启动一个池。]);结束poolSize = p.NumWorkers;pctRunOnAll“mpiSettings (“DeadlockDetection”、“关闭”);“
开始平行池(parpool)使用“bigMJS”概要文件…连接到12个工人。

基准测试函数

我们想基准矩阵左部(\),而不是进入的成本spmd块,所花费的时间创建一个矩阵,或其他参数。因此我们单独解决的数据生成的线性系统,并测量只有时间做后者。我们生成输入数据使用二维block-cyclic codistributor,因为这是最有效的分配方案求解一个线性系统。我们的基准测试然后由测量的时间完成所有的工人解决线性系统A * x =。再一次,我们试图消除任何可能的来源的开销。

函数[A, b] = getData (n)流(创建一个矩阵的大小% d - % d。\ n”n, n);spmd%使用codistributor通常提供了最佳性能%为解决线性系统。codistr = codistributor2dbc (codistributor2dbc.defaultLabGrid,codistributor2dbc.defaultBlockSize,“上校”);一个= codistributed。兰特(n, n, codistr);b = codistributed。兰特(n, 1, codistr);结束结束函数时间= timeSolve (A, b)spmd抽搐;x = \ b;% #好< NASGU >我们不需要x的值。时间=共和党(@max, toc);%的时间来完成。结束时间= {1};结束

选择问题的大小

就像许多其他的并行算法,并行求解一个线性系统的性能很大程度上取决于矩阵的大小。我们的先天的因此,计算预期是:

  • 有些低效率的小型矩阵

  • 非常高效的大型矩阵

  • 效率低下,如果矩阵太大融入系统内存和操作系统开始把内存交换到磁盘

因此,重要的是为许多不同的时间计算矩阵的大小来了解“小”“大”和“太大”意味着在这种情况下。基于先前的实验,我们预计:

  • “太小”矩阵的大小1000 -,- 1000

  • “大”矩阵占领略低于45%的可用内存为每个工人

  • “太大”矩阵占据50%或更多可用的系统内存每个工人

这些是启发式,版本之间的精确值可能会改变。因此,重要的是,我们使用跨整个范围的矩阵大小并验证预期的性能。

注意,通过改变大小根据工人的数量问题,我们采用弱扩展。其他基准测试的例子,如简单的基准测试PARFOR使用21点基准测试独立工作在集群上也采用弱扩展。这些例子基准任务并行计算,其弱比例由使迭代次数与工人的数量成正比。然而,这个例子是基准测试数据并行计算,因此我们将矩阵的大小上限与工人的数量。

%宣布矩阵的大小范围从- 1000到1000 - 45%的系统%每个工人的可用内存。maxMemUsagePerWorker = 0.45 * memoryPerWorker * 1024 ^ 3;%的字节。maxMatSize =圆(√maxMemUsagePerWorker * poolSize / 8));maxMatSize matSize =圆(linspace(1000年,5));

比较性能:吉拍

我们用每秒浮点运算的数量作为衡量性能,因为让我们来比较算法的性能不同的矩阵大小和不同数量的工人。如果我们成功地测试的性能矩阵离开部门足够广泛的矩阵大小,我们期望的性能类似于下面的图:

通过生成这样的图表,我们可以回答这样的问题:

  • 最小的矩阵很小,我们表现不佳?

  • 我们看到一个性能降低时,矩阵是如此巨大,以至于占用系统内存总量的45% ?

  • 什么是最佳的性能,我们可以实现对给定数量的工人?

  • 矩阵的大小16个工人执行比8工人吗?

  • 系统内存限制峰值性能吗?

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

函数gflops = benchFcn (n) numReps = 3;[A, b] = getData (n);时间=正;%几次我们解决线性系统和计算吉拍%根据最好的时间。itr = 1: numReps tcurr = timeSolve (A, b);如果itr = = 1流(执行时间:% f ',tcurr);其他的流(”,% f ',tcurr);结束时间= min (tcurr、时间);结束流(' \ n ');失败= 2/3 * n ^ 3 + 3/2 * n ^ 2;gflops =失败/时间/ 1 e9;结束

执行标准

在完成所有的设置,它是简单的执行标准。然而,计算可能需要很长时间才能完成,所以我们打印一些中间状态信息完成每个矩阵大小的基准测试。

流([与% d开始基准不同的矩阵大小不等\ n”从% d - % d % d % d。\ n”),长度(matSize) matSize (1) matSize (1) matSize(结束),matSize(结束));gflops = 0(大小(matSize));i = 1:长度(matSize) gflops (i) = benchFcn (matSize(我));流(“吉拍:% f \ n \ n”gflops(我));结束结果。matSize = matSize;结果。gflops = gflops;
基准测试5个不同的矩阵大小从1000年开始,由- 76146 - 1000 - 76146。创建一个矩阵的大小1000 - - 1000。工人们…做分析和传输文件。执行时间:1.038931,0.592114,0.575135吉拍:1.161756创建一个矩阵的大小19787 - - 19787。执行时间:119.402579,118.087116,119.323904吉拍:43.741681创建一个矩阵的大小38573 - - 38573。执行时间:552.256063,549.088060,555.753578吉拍:69.685485创建一个矩阵的大小57360 - - 57360。执行时间:3580.232186,3726.588242,3113.261810吉拍:40.414533创建一个矩阵的大小76146 - - 76146。执行时间:9261.720799,9099.777287,7968.750495吉拍:36.937936

绘制的性能

我们现在可以画出结果,比较预期的图如上所示。

无花果=图;ax =轴(“父”图);情节(ax, matSize / 1000 gflops);行= ax.Children;行。标志=“+”;ylabel (ax,“吉拍”)包含(ax,“成千上万的矩阵大小”)titleStr = sprintf ([“解决一个\ \ b为不同的矩阵大小的' % d工人),poolSize);标题(ax, titleStr,“翻译”,“没有”);

如果基准测试结果不如你所想的那样,这里有一些事情要考虑:

  • 底层实现使用ScaLAPACK,证明高性能的声誉。因此,不太可能的算法或图书馆导致效率低下,而是使用它的方式,如下所描述的物品。

  • 如果矩阵太小或太大的集群,由此产生的性能会差。

  • 如果网络通信缓慢,表现将受到严重冲击。

  • 如果cpu和网络通信都是非常快的,但数量的内存是有限的,有可能你不能基准与足够大的矩阵充分利用可用的cpu和网络带宽。

  • 终极性能,重要的是使用一个定制版本的MPI网络设置,并以这样一种方式运行的工人的沟通是通过共享内存。然而,超出了这个例子来解释的范围如何确定和解决这些类型的问题。

比较不同数量的工人

现在我们看看如何比较不同数量的工人通过查看获得的数据通过运行这个示例使用不同数量的工人。获得这些数据在不同的集群从上面的一个。

其他的例子如基准测试独立工作在集群上解释说,当基准测试并行算法对不同数量的工人,一个通常雇弱扩展。也就是说,增加员工的数量,我们增加大小比例的问题。在矩阵的情况下离开部门,我们必须显示额外的护理,因为部门的性能很大程度上取决于大小的矩阵。下面的代码创建了一个图形性能的吉拍所有矩阵的大小,我们测试了不同数量的工人,因为这给了我们最详细的性能特征矩阵左部在这个特定的集群

s =负载(“pctdemo_data_backslash.mat”,“workers4”,“workers8”,“workers16”,“workers32”,“workers64”);无花果=图;ax =轴(“父”图);情节(ax, s.workers4.matSize。s.workers4.gflops / 1000,s.workers8.matSize。s.workers8.gflops / 1000,s.workers16.matSize。s.workers16.gflops / 1000,s.workers32.matSize。s.workers32.gflops / 1000,s.workers64.matSize。/ 1000,s.workers64.gflops);行= ax.Children;集(线,{“标记”},{“+”;“o”;“v”;“。”;‘*’});ylabel (ax,“吉拍”)包含(ax,“成千上万的矩阵大小”)标题(ax,的比较数据求解\ \ b不同数量的工人);传奇(“4个工人,“8工人,的16个工人,“32工人,64年的工人,“位置”,“西北”);

我们注意到的第一件事当看上图,64名工人允许我们解决更大的线性系统方程比是可能的,只有4个工人。此外,我们可以看到,即使一个人可以用一个矩阵的大小60000 - 4日- 60000工人,我们会得到一个性能大约只有10吉拍。因此,即使4工人有足够的内存来解决这样的一个大问题,不过64名工人将大大超越他们。

观察曲线的斜率4工人,我们可以看到,只有适度的三大矩阵大小之间的性能提升。比较这个和前面的图的预期性能一个\ b对于不同大小的矩阵,我们得出结论,我们非常接近实现最佳性能与矩阵的大小7772 - 4工人- 7772。

看着8和16个工人的曲线,我们可以看到,性能下降最大矩阵大小,表明我们正在接近或已经耗尽可用的系统内存。然而,我们看到,第二和第三之间的性能提升最大矩阵大小非常谦虚,表示某种稳定性。因此我们推测与8或16个工人工作时,我们很可能不会看到显著增加吉拍如果我们增加较大的系统内存和测试矩阵大小。

看着32和64名工人的曲线,我们可以看到,有一个显著的性能提高之间的第二和第三大矩阵大小。64年的工人,还有一个显著的性能提高最大的两个矩阵之间的大小。因此我们推测,我们的系统内存32和64名工人在我们已达到最佳性能。如果这是正确的,那么电脑都允许我们添加更多的内存来解决更大的问题,在这些大的矩阵大小表现更好。

加速

传统的统计方法获得的加速与线性代数算法如反斜杠是比较峰值性能。因此我们计算吉拍达到的最大数量为每个工人的数量。

peakPerf =[马克斯(s.workers4.gflops)、马克斯(s.workers8.gflops),马克斯(s.workers16.gflops)、马克斯(s.workers32.gflops),马克斯(s.workers64.gflops)];disp (的峰值性能吉拍4 - 64工人:“)disp peakPerf disp (加速时从4工人8,16日32和64名工人:“)disp (peakPerf(2:结束)/ peakPerf (1))
峰值性能在吉拍4 - 64工人:10.9319 23.2508 40.7157 73.5109 147.0693加速时从4工人8,16日32和64名工人:2.1269 3.7245 6.7244 13.4532

我们因此得出结论,我们得到一个大约13.5的加速增加工人的数量16倍,从64工人。正如我们上面所提到的,性能图表明,我们可能会增加64名员工上的性能(从而进一步提高加速),通过增加集群计算机系统内存。

使用的集群

这个数据是使用16双处理器,生成octa-core电脑,每一边有64 GB的内存,与千兆以太网相连。当使用4个工人,他们都是在一个电脑。我们使用2电脑8工人,4电脑16工人等。

重新启用活动的死锁检测

现在我们总结基准,我们可以安全地重新启用当前并行死锁检测池。

pctRunOnAll“mpiSettings (“DeadlockDetection”、“on”);”
结束
ans =结构体字段:matSize:(1000 19787 38573 57360 76146] gflops: (1.1618 43.7417 - 69.6855 40.4145 - 36.9379)