预测MPI程序运行时间的方法与流程

文档序号:12824534阅读:555来源:国知局
预测MPI程序运行时间的方法与流程

本发明涉及程序性能预测技术领域,尤其涉及一种预测mpi程序运行时间的方法。



背景技术:

在超级计算机系统(以下简称超算系统)的运行过程中,其作业调度系统负责对用户提交的作业进行作业调度操作,为了提高系统的整体利用效率,调度系统需要得知作业的运行时间以更好的安排作业队列。而在超级计算机系统中运行的作业程序通常为mpi程序,因此如何对mpi程序进行运行时间预测得到了越来越多的关注。

目前在超算系统中常用的方法为经验估计,即根据用户以往提交的程序的运行时间估计之后用户提交的程序的运行时间。这种方法针对重复运行的用户程序具有一定的效果,但是难以对大部分程序产生应有的预测效果。此外,有其他研究人员提出了其他预测方法,可以分为基于数学模型的分析和基于运行数据的分析两种。

基于数学模型的分析即通过分析程序本身的数学模型,结合实际运行系统的特性,得出程序的最终运行模型,从而能够对程序的运行时间进行细致的分析。但是这种方法对于研究人员的要求非常高,通常要求研究者同时具备多个领域的专业知识背景,并且研究过程较为耗时。此外,当程序发生变更,或者运行环境发生改变,就必须重新对程序进行建模。

基于运行数据的分析,根据数据的获取途径不同,可以分为若干种不同的技术,如基于基准程序、基于程序运行状态采样、基于骨架程序、基于代码插装技术等等。

基于基准程序的预测技术主要用于更换运行环境后的程序性能预测,即使用一组基准程序作为比较对象,测出基准程序在不同运行环境下的性能变化,以此估计待测程序的性能变化。这种技术易于实行,但是基准程序的代表性的优劣决定了最终的预测准确度。

基于程序运行状态采样的预测技术即通过监控程序运行中的系统状态数据,通过一定的模型分析,得出状态数据与程序运行时间的关联关系。这种技术通常需要运行环境的支持,并且为了不过多消耗系统资源,监控粒度不能做到任意小,并且不能根据程序的输入情况预测其运行时间。

基于骨架程序的预测技术即通过某种方式得到一个简化版的程序,称为骨架程序。骨架程序与原程序的运行时间保持一定的比例,最终通过运行骨架程序推算出原程序的运行时间。这种技术的问题在于很难获得一个较优的骨架程序,使得骨架程序与原程序之间保持适当的比例。并且由于该技术缩减了原程序中的大量代码,极有可能遗漏特定输入下的运行状态,从而使得预测变得不准确。

基于代码插装技术的预测是一种通过修改程序代码提取程序运行特征的技术。主要做法是通过修改源程序,在不改变源程序语义的前提下,插入特定代码,使修改后的程序可以输出与程序逻辑相关的特征信息,从而用于后续的预测模型的建立。但是目前该技术还并不能适用于mpi程序的特征提取,经过调研,也没有发现其他基于代码插装技术的针对mpi程序的特征提取工具。而在高性能计算领域,大多数应用都使用了mpi技术,因此需要针对现有技术进行优化使得其适用于mpi程序。



技术实现要素:

本发明的目的是提供一种预测mpi程序运行时间的方法,可以准确预测mpi程序运行时间,同时,对于程序的输入不敏感,无需使用者考虑特殊输入情况。

本发明的目的是通过以下技术方案实现的:

一种预测mpi程序运行时间的方法,包括:

对待预测的mpi程序中的待处理语句进行定位;

在待处理语句中需要计数的语句之后加入计数语句,并且,在待处理语句中的mpi函数之后加入mpi特征数据计数语句;

根据加入的计数语句与mpi特征数据计数语句,生成变量,并写入头文件中,进而获得处理后的mpi程序;

根据头文件中的变量名自动生成用于输出计数值的语句,并且对处理后的mpi程序运行过程中,各个节点产生的mpi特征数据进行整合操作;

根据处理后的mpi程序输出的计数值和整合后的mpi特征数据,获得预测模型;

使用处理后的mpi程序获取待预测的mpi程序的运行特征数据,并输入所述预测模型中,最终获得待预测的mpi程序运行时间的预测值。

所述对待预测的mpi程序中的待处理语句进行定位包括:

使用libtooling工具库,采用其提供的visitstmt函数,配合isa<forstmt>、isa<dostmt>和isa<whilestmt>三个函数来定位三种循环语句,配合isa<ifstmt>函数定位条件分支语句;使用工具库中提供的visitcall函数,配合工具库中的callepxr.getdirectcallee和functiondecl.getnameasstring函数并利用mpi函数名实现对mpi函数的定位。

所述在待处理语句中需要计数的语句之后加入计数语句包括:

需要计数的语句为待处理语句中的循环语句与条件分支语句;

在获取到循环语句与条件分支的位置后,首先根据位置信息进行计数变量名称的生成,同时在对应的位置后部插入计数语句,用于程序运行时进行计数。

在插入计数语句过程中,需要对插入位置进行判断;

在处理循环语句时,首先判断循环语句是否被大括号包裹,若否,则需要手动添加大括号;判断的方法是使用isa方法检测循环语句是否为compoundstmt类型,如果是,则说明循环语句已经包含在大括号中,否则需要使用lexer::measuretokenlength(),stmt.getlocstart()和stmt.getlocend()方法结合,为循环语句加入大括号;

对于条件分支语句,需要分别对then和else部分进行判断,其他操作与循环语句操作相同。

在待处理语句中的mpi函数之后加入mpi特征数据计数语句包括:

mpi特征数据,发生在发送、收取和集群通信这几类函数中;

通过callexpr.arg_begin()函数获取到mpi函数的参数列表,之后通过查询mpi函数的参数含义,对参数进行摘取并进行计数语句的拼凑。

所述对处理后的mpi程序运行过程中,各个节点产生的mpi特征数据进行整合操作包括:

对节点的特征数据进行求均值的计算作为最终输出:

其中,f为整合后的mpi特征数据,i为节点编号,f1,i表示第1个mpi特征在第i个节点上的记录值,n为节点总数,k为单节点的mpi特征数据,即表示第k个特征在所有节点上的记录平均值。

所述根据处理后的mpi程序输出的计数值和整合后的mpi特征数据,获得预测模型包括:

所输出的计数值包含了循环语句的计数值、条件分支语句的计数值,以及mpi特征的计数值;所述的循环语句、条件分支语句以及mpi特征统称为特征;

则获取预测模型的过程如下:

首先,使用m组不同的输入运行处理后的mpi程序,输出m组所有特征的特征数据,设获取到的特征共有n种,记所有的n种特征的特征数据组成了输入x,对应的m次程序运行的时间为y,其中:

x=(x1,x2,…,xn)

y=(y1,y2,…,ym);

然后,对x和y迭代进行多次多元回归分析,重复如下步骤:

1)使用多元一次函数对x和y做一次拟合,得到:

y=ax+b=a1x1+a2x2+...+anxn+b

其中,

a=(a1,a2,…,an);

b为一个常数;

2)将上式中绝对值排名前p位的a对应的特征数据xi(i∈1,2,…,n)保留,记:

x'=(x1',x'2,…,x'p)

并令x=x',重复步骤1)直到被保留的特征数量达到预设目标,记此时剩余的特征数据为x*;

最后,利用x*和y进行建模,获得预测模型。

使用处理后的mpi程序获取待预测的mpi程序的运行特征数据,并输入所述预测模型中,最终获得待预测的mpi程序运行时间的预测值包括:

在得到预测模型后,需要对处理后的mpi程序进行二次处理,即根据预测模型中的变量,选择需要在程序中保留的特征计数语句,当预测模型中的所有需要保留的特征计数语句确定之后,在相应位置插入强制返回语句;

使用二次处理后的mpi程序,获取待预测的mpi程序的运行特征数据,并输入所述预测模型中,最终获得待预测的mpi程序运行时间的预测值。

由上述本发明提供的技术方案可以看出,针对传统技术无法对mpi特征进行采集和整合的问题予以修正,并且将基于代码插装的程序特征获取技术扩展到了高性能计算领域中常用的c/c++语言。同时本发明对于程序的输入不敏感,无需使用者考虑特殊输入情况。

附图说明

为了更清楚地说明本发明实施例的技术方案,下面将对实施例描述中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图仅仅是本发明的一些实施例,对于本领域的普通技术人员来讲,在不付出创造性劳动的前提下,还可以根据这些附图获得其他附图。

图1为本发明实施例提供的一种预测mpi程序运行时间的方法的流程图。

图2为本发明实施例提供的mpi程序处理过程示意图;

图3为本发明实施例提供的预测mpi程序运行时间的示意图。

具体实施方式

下面结合本发明实施例中的附图,对本发明实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本发明一部分实施例,而不是全部的实施例。基于本发明的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都属于本发明的保护范围。

图1为本发明实施例提供的一种预测mpi程序运行时间的方法的流程图;如图1所示,其主要包括如下步骤:

步骤11、对待预测的mpi程序中的待处理语句进行定位。

本发明实施例中,可以使用开源的编译器前端clang中提供的libtooling工具库,采用其提供的visitstmt函数,配合isa<forstmt>、isa<dostmt>和isa<whilestmt>三个函数来定位三种循环语句,配合isa<ifstmt>函数定位条件分支语句;使用工具库中提供的visitcall函数,配合工具库中的callepxr.getdirectcallee和functiondecl.getnameasstring函数并利用mpi函数名实现对mpi函数的定位。

步骤12、在待处理语句中需要计数的语句之后加入计数语句,并且,在待处理语句中的mpi函数之后加入mpi特征数据计数语句。

本发明实施例中,待处理语句即为循环语句、条件分支语句以及mpi函数3。其中,需要计数的语句为待处理语句中的循环语句与条件分支语句。

1、对于循环语句与条件分支语句。

在获取到循环语句与条件分支的位置后,首先根据位置信息进行计数变量名称的生成,同时在对应的位置后部插入计数语句,用于程序运行时进行计数。

示例性的,根据位置信息进行计数变量名称的生成,如:

for_main_c_100_10;

上述名称表明该变量对main.c中第100行第10列起的for循环进行计数。在名称生成完毕后需要进行保存,以便生成外部头文件,同时在对应的位置后部插入计数语句如for_main_c_100_10++;以便于程序运行时进行计数。

优选的,在插入计数语句过程中,需要对插入位置进行判断,以避免破坏源程序逻辑。在处理循环语句时,首先判断循环语句是否被大括号包裹;若否,则需要手动添加大括号。判断的方法是使用isa方法检测循环语句是否为compoundstmt类型,如果是,则说明循环语句已经包含在大括号中,否则需要使用lexer::measuretokenlength,stmt.getlocstart和stmt.getlocend三个函数相结合,为循环语句加入大括号保证程序的逻辑。对于条件分支语句,需要分别对then和else部分进行判断,其他操作与循环语句操作相同。

2、对于mpi函数调用。

mpi特征数据(即mpi通信量),主要发生在发送、收取和集群通信这几类函数中;

通过callexpr.arg_begin函数获取到mpi函数的参数列表,之后通过查询mpi函数的参数含义,对参数进行摘取并进行计数语句的拼凑。

示例性的,对于mpi_send,可以得到如下结果:

mpi_allreduce_main_c_100_10+=1*sizeof(mpi_int);

其中1是mpi_allreduce函数中的sendcount的值,整个变量的值为该次通信的通信量估算值,单位为byte。对于mpi_sendrecv之类同时存在发送和收取的函数,由于本节点的发送会被其他进程记录为接收,因此仅需记录其发送量即可。

步骤13、根据加入的计数语句与mpi特征数据计数语句,生成变量,并写入头文件中,进而获得处理后的mpi程序。

在前面的步骤中存储的变量名,应当在文件处理完毕后写入一个头文件,并在当前文件中包含生成的头文件。头文件中变量一律声明为int型,而在被处理的文件中,使用extern关键字引用头文件中的变量。

示例性的,在main.c中:

#include“header.h”

externintfor_main_c_100_10;

本发明实施例中,为了实现处理多文件,采用了中间文件的方式,首先将变量名以附加的模式写入一个中间文件中,并在所有待被处理的文件处理完毕之后使用特定程序生成头文件。

上述步骤11~步骤13的过程可参见图2,通过上述操作步骤后获得目标程序即为“处理后的mpi程序”。

步骤14、根据头文件中的变量名自动生成用于输出计数值的语句,并且对处理后的mpi程序运行过程中,各个节点产生的mpi特征数据进行整合操作。

1、生成用于输出计数值的语句。

为了输出所有的结果,需要根据所有生成的变量名自动生成输出函数进行文件输出操作。

示例性的:

为了对mpi部分进行各节点单独输出,需要在编译时提供参数,同时在输出函数中加入条件编译,如:#ifdefmpi,使得程序能够针对不同运行环境做出相应的改变。同时要保证该print_result函数需要在mpi_finalize之前被调用。

为了避免重复包含带来的函数重复定义的问题,需要将输出函数单独定义在.c文件中,结合.h文件单独生成中间文件后与其他部分一起编译为最终程序。这一步需要结合编译系统进行特别处理,可以参照相关编译系统的说明文档进行。

通过上述方法可以获得每一mpi特征在每一节点的记录值,以便后续的mpi特征数据整合操作。

2、mpi特征数据整合操作。

由于目前mpi程序通常在不同节点上的运行逻辑近似,因此可以对节点的特征数据进行求均值的计算作为最终输出:

其中,f为整合后的mpi特征数据,i为节点编号,f1,i即第1个mpi特征在第i个节点上的记录值,n为节点总数,k为单节点的mpi特征数量,即表示第k个特征在所有节点上的记录平均值。

对mpi集群通信的若干函数进行自动特征提取的实施步骤,可分解如下步骤:

1)、首先获取到callexpr的被调用者并获取到调用的函数的名称。

2)、判断被调用的函数名称是否为需要采集特征的函数名。

3)、如果是需要采集特征的mpi函数,则按照mpi参数规则对参数列表进行输出,将发送数据的部分拼接为数据量计算表达式,并依此生成计数语句并插入在函数调用后。

步骤15、根据处理后的mpi程序输出的计数值和整合后的mpi特征数据(统称为特征数据),获得预测模型。

所输出的计数值包含了循环语句的计数值、条件分支语句的计数值,以及mpi特征的计数值;所述的循环语句、条件分支语句以及mpi特征可统称为特征。

则获取预测模型的过程如下:

首先,使用m组不同的输入运行处理后的mpi程序,输出m组所有特征的特征数据。设获取到特征共有n种,记所有的n种特征的特征数据组成了输入x,对应的m次程序运行的时间为y,其中:

x=(x1,x2,…,xn)

y=(y1,y2,…,ym);

然后,对x和y迭代进行多次多元回归分析,即重复如下步骤:

1)使用多元一次函数对x和y做线性多元回归,得到:

y=ax+b=a1x1+a2x2+...+anxn+b

其中,

a=(a1,a2,…,an)

b为一个常数。

2)将上式中绝对值排名前p位的a对应的特征数据xi(i∈1,2,…,n)保留,记

x'=(x1',x'2,…,x'p)

并令x=x',重复步骤1)直到被保留的特征数量(即p的大小)达到预设目标,记此时剩余的特征数据为x*;在上述迭代过程中,p的数值并非固定;示例性的,例如,第一次迭代时p可以为30,第二次迭代时p可以为10。

最后,利用x*和y分别作为输入和输出进行建模,获得预测模型,此时所使用的模型可以使用任意能够适应预测问题的模型。

步骤16、使用处理后的mpi程序获取待预测的mpi程序的运行特征数据,并输入步骤15中最终获得的预测模型中,即可获得待预测的mpi程序运行时间的预测值。

本发明实施例中,在得到预测模型后,需要对处理后的mpi程序进行二次处理,即根据预测模型中的变量,选择需要在程序中保留的特征计数语句,当预测模型中的所有需要保留的特征计数语句之后,在相应位置插入强制返回语句,如exit(0);。

使用二次处理后的mpi程序,获取待预测的mpi程序的运行特征数据,并输入所述预测模型中,最终获得待预测的mpi程序运行时间的预测值。

本发明实施例所提供的上述方法的具体实施流程可如图3所示。

本发明实施例上述方案,可以clang编译器的libtooling工具库进行构建,使用其代码分析工具进行c/c++程序中的循环、分支语句的定位与计数语句的插入,以及对特定mpi函数的定位操作,之后对多节点产生的特征进行合并操作,进而生成预测模型,实现mpi程序运行时间的预测。该方案针对传统技术中无法对mpi特征进行采集和整合的问题予以修正,并且将基于代码插装的程序特征获取技术扩展到了高性能计算领域中常用的c/c++语言。同时本方案对于程序的输入不敏感,无需使用者考虑特殊输入情况。

以上所述,仅为本发明较佳的具体实施方式,但本发明的保护范围并不局限于此,任何熟悉本技术领域的技术人员在本发明披露的技术范围内,可轻易想到的变化或替换,都应涵盖在本发明的保护范围之内。因此,本发明的保护范围应该以权利要求书的保护范围为准。

当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1