linpack实验:MPI性能参数调优

4 篇文章 0 订阅
3 篇文章 0 订阅

本次教程写的匆忙,也许会有很多勘误欢迎指正

性能优化部分

HPL.dat字段说明

在本实验中,为了不让生成的测试报告太复杂,让N=1,只测试一个矩阵

HPLinpack benchmark input file                             //说明性语句
Innovative Computing Laboratory, University of Tennessee   //说明性语句
HPL.out      output file name (if any)                     //输出文件名
6            device out (6=stdout,7=stderr,file)           //选择输出方式
1            # of problems sizes (N)                       //要测试的矩阵个数
41448        Ns                //不小于上一行的大小,Ns^2*64=节点内存*节点数*8,Ns=0.8~0.9D
//每节点有2G内存,4节点,Ns的算法为Ns^2*64=1024*1024*1024*2*4*8,-〉N=32000~33000,再*0.8~0.9即可
6            # of NBs                                      //分块方法的种数
32 64 96 126 192 256      NBs                                       //分块的大小用196,232,256效果比较好
0            PMAP process mapping (0=Row-,1=Column-major) //处理器阵列 按列排列 or 按行排列
3            # of process grids (P x Q)         //二维处理器网格(P×Q)P×Q=系统CPU数=进程数
2 1 4        Ps                           //P≤Q,这是一个测试经验值,一般来说,P的值尽量取得小一点
2 4 1        Qs
16.0         threshold                                         //阈值
3            # of panel fact                                   //LU分解相关
0 1 2        PFACTs (0=left, 1=Crout, 2=Right)
2            # of recursive stopping criterium
2 4          NBMINs (>= 1)
1            # of panels in recursion
2            NDIVs
3            # of recursive panel fact.
0 1 2        RFACTs (0=left, 1=Crout, 2=Right)
1            # of broadcast
0            BCASTs (0=1rg,1=1rM,2=2rg,3=2rM,4=Lng,5=LnM)
1            # of lookahead depth
0            DEPTHs (>=0)
2            SWAP (0=bin-exch,1=long,2=mix)
64           swapping threshold
0            L1 in (0=transposed,1=no-transposed) form
0            U  in (0=transposed,1=no-transposed) form
1            Equilibration (0=no,1=yes)
8            memory alignment in double (> 0)

保持其他参数不变,只修改P×Q,Ps,Qs三个参数,P×Q是电脑的cpu数目,可以通过如下命令查询:

sudo cat /proc/cpuinfo|grep cores

查看电脑的cpu进程数

sudo cat /proc/cpuinfo | grep processor

作者我的电脑cpu拥有4个cpu核心,共8线程,也就是所谓的“4核心双线程”电脑,即cpu里封装了四个计算核心,每个核心支持同时运行2个进程,所以我的电脑P×Q的最大值就是8,但是我在运行如下指令:

mpirun -np 8 ./xhpl > info.txt

会报如下错误:

在这里插入图片描述

根据查阅各种资料,应该是openMpi对电脑性能的错估造成的,可通过如下命令解决:

mpirun -oversubscribe -np 8 ./xhpl > info.txt

实践证明当加入了-oversubscribe字段后,线程数可以写的很大,但我不建议这么做,因为进程数如果大于cpu支持的最大进程数,那么会触发操作系统的进程调度,会大幅度降低性能,所以我们一般不要超过最大进程数。

我们要通过调参来找出性能最佳的参数,在HPL.dat中,我们可以去修改的,有矩阵阶数Ns,块大小NB,以及进程数P×Q,我们可以分为下面三组实验进行:

(1)改变测试线程数

分别在进程数为1,2,4,8四种情况下执行,注意要同步修改HPL.dat下的P×Q,Ps,Qs,画出相应的表格和曲线,根据控制变量法,在一组实验中要保持Ns和NB不变,可以在不同组实验中改变Ns和NB,为了减少实验数量,我们不改变Ns和NB,固定他们不变,测定进程数目的改变对性能的影响

在Ns=19200,NB=256(可变,多测几组效果更佳)的情况下,填写下面的表格:

进程数PQ峰值性能
111
212
221
414
422
441
818
824
842
881
16116
1628
1644
1682
16161

得出在不同线程数下最佳的P,Q值:

线程数最佳P最佳Q
1
2
4
8
16

记录其中峰值性能最高的一组P,Q

(2)分块优化性能

在HPL.dat文件中,NB表示分块大小,先要修改NB种数,再根据种数写分块大小:

4            # of NBs                                      //分块方法的种数
1 2 3 4      NBs                                       //分块的大小用196,232,256效果比较好

HPL默认值是有四种分块,可以分为1x1,2x2,3x3,4x4四种,这些分块可能太小了,根据资料中的经验值,分块采用192,232,256效果比较好,我们不妨采用等步长的方式,来确定最佳的分块大小。

①保持进程数目不变,测定不同Ns值下块大小对性能的影响

在上面得到的峰值性能最高的一组P,Q,完成表格:

GflopsNB=32NB=64NB=96NB=128NB=160NB=192NB=224NB=256
Ns=1920
Ns=3840
Ns=5760
Ns=7680

绘制曲线

②保持Ns不变,测定不同进程数(P,Q取最佳)下块大小对性能的影响

GflopsNB=32NB=64NB=96NB=128NB=160NB=192NB=224NB=256
1线程
2线程
4线程
8线程
16线程

绘制曲线

(3)改变Ns

选取P,Q(峰值性能最高的一组P,Q)

GflopsNs=4000Ns=7000Ns=10000Ns=13000Ns=16000Ns=19000Ns=41448(这是我电脑的最佳理论值)
NB=32
NB=64
NB=96
NB=128
NB=160
NB=192
NB=224
NB=256

经过三个实验,可以初步粗略得到如何调参可以使性能最优

下面是作者实际实验的数据:
先介绍下如何跑测试

跑测试运行的指令格式如下:

mpirun -np 2 ./xhpl > 1920-32-1-2.txt

注意:为了写报告以及管理实验数据方便,txt文件的命名采用格式Ns-NB-P-Q.txt

mpirun是mpi执行可执行文件的一个程序,-np后跟着进程数(一定等于PxQ),./xhpl是hpl编译生成的一个默认的测试程序,当然我们也可以自己去书写带有mpi的c或者c++代码,编译后用mpirun执行

我们在测试的时候要不断的改参数,十分的麻烦,为此,作者写了一个python脚本,便于读者完成自动化测试,代码如下:

import os
from tqdm import tqdm #这个库需要用pip先安装一下
class MPIRun:
    def __init__(self,Ns,NB,P,Q):
        self.Ns = Ns
        self.NB = NB
        self.P = P
        self.Q = Q
        self.HPLDAT = '''HPLinpack benchmark input file
Innovative Computing Laboratory, University of Tennessee
HPL.out      output file name (if any)
6            device out (6=stdout,7=stderr,file)
1            # of problems sizes (N)
%d           Ns
1            # of NBs
%d           NBs
0            PMAP process mapping (0=Row-,1=Column-major)
1            # of process grids (P x Q)
%d       Ps
%d       Qs
16.0         threshold
3            # of panel fact
0 1 2        PFACTs (0=left, 1=Crout, 2=Right)
2            # of recursive stopping criterium
2 4          NBMINs (>= 1)
1            # of panels in recursion
2            NDIVs
3            # of recursive panel fact.
0 1 2        RFACTs (0=left, 1=Crout, 2=Right)
1            # of broadcast
0            BCASTs (0=1rg,1=1rM,2=2rg,3=2rM,4=Lng,5=LnM)
1            # of lookahead depth
0            DEPTHs (>=0)
2            SWAP (0=bin-exch,1=long,2=mix)
64           swapping threshold
0            L1 in (0=transposed,1=no-transposed) form
0            U  in (0=transposed,1=no-transposed) form
1            Equilibration (0=no,1=yes)
8            memory alignment in double (> 0)'''%(Ns,NB,P,Q)
    
    def run(self):
        HPLDAT_FILE = open("./HPL.dat","w",encoding="utf-8")
        HPLDAT_FILE.write(self.HPLDAT)
        HPLDAT_FILE.close()
        cmd = "mpirun -np %d ./xhpl > %d-%d-%d-%d.txt"%(self.P*self.Q,self.Ns,self.NB,self.P,self.Q)
        print("\r",cmd,end="",flush=True)
        os.system(cmd)


if __name__=="__main__":
    script_deal = open("./script.txt","r",encoding="utf-8")
    lines = script_deal.readlines()
    for line in tqdm(lines):
        runlist = [int(i) for i in line.split(" ")]
        Ns,NB,P,Q = runlist[0],runlist[1],runlist[2],runlist[3]
        mpirun = MPIRun(Ns,NB,P,Q)
        mpirun.run()

使用程序前,首先要编写script.txt,记录需要做的实验参数,例子如下:

26214 192 1 2
26214 224 1 2
26214 256 1 2

这个例子就是要做三组测试,每行对应着一组实验的参数,将script.txt和上述python脚本一起放在你的test文件夹下,执行即可开始测试(python脚本十分容易理解,读者看看就会用了)

在这里作者建议读者不要一次性把所有实验都做完,因为有的测试需要的时间非常的长(可能长达1h或更长),建议结合自己的时间安排,合理安排测试数量,不要浪费时间(写这个脚本的目的也是能让你们睡觉的时候也能跑测试)

然后作者通过几天断断续续的测试,得到了如下的实验结果:

(1)改变测试进程数

在Ns=19200, NB=256的条件下进行实验:

进程数PQ峰值性能GFLOPS
11148.452
21272.299
22169.891
41461.060
42249.735
44118.128
81862.019
82463.353
84261.770
88156.499
1611659.354
162860.713
164458.937
168253.201
1616141.334
线程数最佳P最佳Q
111
212
414
824
1628
//绘图代码,复制到echarts官网可直接画出图,记得修改data数组
var data = [
    [[1,1,48.452,'48.452'],[1,2,72.299,'72.299'],[2,1,69.891,'69.891'],[1,4,61.060,'61.060'],[2,2,49.735,'49.735'],[4,1,18.128,'18.128'],[1,8,62.019,'62.019'],[2,4,63.353,'63.353'],[4,2,61.770,'61.770'],[8,1,56.499,'56.499'],[1,16,59.354,"59.354"],[2,8,60.713,"60.713"],[4,4,58.937,"58.937"],[8,2,53.201,"53.201"],[16,1,41.334,"41.334"]],
];

option = {
    xAxis: {
        name:"P"
    },
    yAxis: {
        scale: true,
        name:"Q"
    },
    series: [{
        data: data[0],
        type: 'scatter',
        symbolSize: function (data) {
            return data[2];
        },
        emphasis: {
            focus: 'self'
        },
        labelLayout: {
            y: 20,
            align: 'center',
            hideOverlap: true,
            moveOverlap: 'shiftX'
        },
        labelLine: {
            show: true,
            length2: 5,
            lineStyle: {
                color: '#bbb'
            }
        },
        label: {
            show: true,
            formatter: function (param) {
                return param.data[3];
            },
            minMargin: 10,
            position: 'top'
        }
    }]
};

在这里插入图片描述

​ 根据上图所示,圆的半径反映了性能的大小,可见,当P越小,圆的半径普遍较大,所以我们让最佳的P,Q取P=1,Q=x(当然实际上一些P=2的情况会更优,但P=1性能也很好,这里我们采取网友们的普遍结论),而且我们观察到,P=1,Q=2时性能是极佳的

(2)分块优化性能

①保持进程数目不变,测定不同Ns值下块大小对性能的影响

由上个实验所得出的结论,P=1,Q=2时,性能最好,我们就在这个条件下进行试验

GflopsNB=32NB=64NB=96NB=128NB=160NB=192NB=224NB=256
Ns=192055.49264.15763.43361.82460.85658.97057.62157.816
Ns=384041.97262.38964.16366.04965.05364.89762.57663.057
Ns=576044.49369.65470.53572.18571.51470.45672.00772.132
Ns=768041.08256.98371.76172.80364.29971.13271.81369.620

在这里插入图片描述

对于作者的计算机,在块大小为128时,性能很高,并且这种高几乎不随Ns的变化(Ns取不同值)而变化

②保持Ns不变,测定不同进程数(P,Q取最佳)下块大小对性能的影响

我们选取Ns=5760,进行以下实验

GflopsNB=32NB=64NB=96NB=128NB=160NB=192NB=224NB=256
1x139.28042.64340.98042.23242.24040.86042.53643.965
1x244.49369.65470.53572.18571.51470.45672.00772.132
1x414.98622.92929.96133.50134.48136.44436.83737.956
1x828.07039.35738.16536.60435.63534.79734.46534.918
1x1621.99226.38625.31626.02725.02024.36524.51527.128

在这里插入图片描述

对于作者的计算机,无论在哪种进程配置下,分块为128时的性能都是极佳的,看来我们可以说128就是作者计算机的最佳分块大小。

(3)改变Ns

首先计算自己计算机的最佳Ns理论值,满足:
N s 2 × 64 = 1024 × 1024 × 1024 × 内 存 大 小 ( G B 为 单 位 ) × 8 Ns^2×64=1024×1024×1024×内存大小(GB为单位)×8 Ns2×64=1024×1024×1024×GB×8
如果计算机的内存是8GB,那么Ns的最佳理论值应该是26214

在P=1,Q=2的条件下,进行实验

GflopsNs=4000Ns=7000Ns=10000Ns=13000Ns=16000Ns =19000Ns=26214(这是作者电脑的最佳理论值)
NB=3247.85944.14445.67446.31546.37047.61445.270
NB=6469.57770.66067.50671.03569.95368.43363.181
NB=9670.78972.26268.90867.28771.17474.20265.766
NB=12870.65574.47877.85779.50472.06074.23068.085
NB=16067.12972.63075.57676.19068.40574.45368.958
NB=19268.20875.33076.79778.83875.63269.76969.856
NB=22467.66775.13177.57172.23272.22569.38868.200
NB=25667.65273.73578.48173.04573.94370.42069.858

在这里插入图片描述

观察上图,可见,在Ns=13000时,性能极佳,当然在NB不同时会有偏移。

由此观之,作者的计算机在P=1,Q=2,Ns=13000,NB=128的时候会取到最佳性能,当然Ns和NB由于实验粒度太大,得到的只是粗略的估计值,只作为参考。

  • 6
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
MPI是一种用于并行计算的通信协议,它允许不同的进程在分布式计算环境中相互通信和协作。在使用MPI执行并行计算时,调优MPI性能参数可以显著提高系统的性能。下面介绍一些调优MPI性能参数的方法。 1. 调整通信域大小 MPI性能的一个重要因素是通信域的大小。通信域指的是进程之间交换消息的逻辑区域。通信域越大,通信的开销就越大。为了提高MPI性能,可以尝试调整通信域的大小,以最小化通信开销。可以使用MPI_Comm_split函数将通信域划分为更小的子域,以减少通信开销。 2. 调整进程数 MPI性能还受到进程数的影响。如果进程数太少,可能会导致通信开销过大,从而影响性能。相反,如果进程数太多,可能会导致过多的通信和同步开销。为了获得最佳性能,需要找到最佳的进程数。可以使用MPI_Comm_size函数确定当前通信域中的进程数,并使用MPI_Comm_split函数将进程划分为更小的组。 3. 选择适当的通信模式 MPI支持多种通信模式,包括点对点通信、广播、归约和收集。每种通信模式都有其优点和缺点,因此选择适当的通信模式对于提高MPI性能至关重要。例如,在点对点通信中,发送方需要等待接收方确认消息已经接收。这种通信模式可能会导致延迟。相反,在广播通信中,所有进程都可以同时接收消息,因此可以提高性能。 4. 调整缓冲区大小 MPI通信期间使用缓冲区,以存储要发送或接收的数据。缓冲区的大小对MPI性能有重要影响。如果缓冲区太小,可能会导致进程必须等待缓冲区可用,从而导致延迟。相反,如果缓冲区太大,可能会导致内存消耗过多。为了获得最佳性能,需要根据应用程序的需求来调整缓冲区大小。 5. 调整MPI实现 MPI实现是指MPI库的实现方式。不同的MPI实现可能会导致不同的性能。为了获得最佳性能,可以尝试使用不同的MPI实现,并比较它们的性能。常见的MPI实现包括OpenMPIMPICH和Intel MPI

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值