一种数值程序的全局优化方法转让专利

申请号 : CN201810001948.7

文献号 : CN108228187B

文献日 :

基本信息:

PDF:

法律信息:

相似专利:

发明人 : 王协肖安祥汤恩义王林章马骏李宣东

申请人 : 南京大学

摘要 :

本发明提出了一种数值程序的全局优化方法,利用符号执行技术从源程序中抽取用于表述路径约束条件以及数值计算过程的代数表示。并分析每个代数表示,通过运用不同地代数变换规则将其转换成数值计算误差更小的代数形式。最终把每个代数表示转成相应的代码片段,并将它们组合生成目标程序。本发明具有以下优势:所有过程均为自动化过程,无需人为干预;程序编写者可以更专注于业务逻辑,而无需关心与数值分析相关的细节操作。这样既提高了开发效率,又使代码逻辑直观易懂,易于维护。

权利要求 :

1.一种数值程序的全局优化方法,其特征在于该方法通过符号执行技术抽取关于数值程序计算过程的全局代数表示,不断寻找数值误差更小的代数表示,从而使得数值计算得到优化,具体步骤为:

1-1)、利用符号执行技术动态执行原始数值程序,记录数值程序的结构信息、每条执行路径的路径约束条件以及计算过程的代数表示;

1-2)、分别分析步骤1-1)收集的每个代数表示的全局形式,运用代数变换规则将原代数表示形式优化成数值计算误差更小的代数表示形式,再使用区间分析技术检验变换后代数形式的正确性,从而完成对每个代数表示形式的优化;

1-3)、遍历原始程序的抽象语法树以及步骤1-2)生成的经过优化的代数表示形式,将代数表示形式对应的代码拼接到语法树节点中路径约束的提取位置合成所有代码片段,最终构成目标程序;

其中所述的步骤1-2)中运用代数变换规则将原代数表示形式转换成数值计算误差更小的代数表示形式,具体过程如下:

3-1)、初始化原始代数表示集合F;

3-2)、对于F中的每个代数表示E,构建代数表示集合S={E};

3-3)、用户任选一种配置好的选择策略包括随机策略、机器学习、或者遗传算法策略,并按照该策略从S中选取一个代数表示Ei,并任选一种选择策略从变换规则集中选取一个数学代数变换规则Ri,将Ri应用于Ei生成一个数学等价的代数表示Ei';

3-4)、使用区间分析技术分析Ei'的误差区间是否扩大,如果没有扩大,则代数表示Ei'即为原始代数表示E的优化结果,将E从原始代数表示集合F中移除,跳转到步骤3-6);否则,执行步骤3-5);

3-5)、将代数变换后的代数表示Ei'加入代数表示S,跳转回到步骤3-3);

3-6)、判断原始代数表示集合F是否还存在待优化的代数表示,如果存在,跳转回到步骤3-2);否则,优化过程结束。

2.根据权利要求1所述的一种数值程序的全局优化方法,其特征在于所述步骤1-1)中利用符号执行技术动态执行原始数值程序,记录数值程序的结构信息、每条执行路径的路径约束条件以及计算过程的代数表示,它的输出是一棵抽象语法树;该抽象语法树只有四种节点,分别为代数表示节点,基本语句块节点,分支节点和循环节点;代数表示节点是数值程序计算过程的抽象,用于记录符号的代数表示;基本语句块节点用于表示数值程序的顺序结构,它的子节点可以由任意四种节点按序构成;分支节点用于表示数值程序的分支结构;循环节点用于抽象数值程序的循环结构,通过循环节点可以将循环的计算过程抽象成为一条累积求值表达式,整个抽象语法树抽象了数值程序的结构信息以及计算过程。

3.根据权利要求1或2所述的一种数值程序的全局优化方法,其特征在于所述的抽象语法树,其构造过程具体如下:

2-1)、启动符号执行,初始化根节点为基本块节点,在执行过程中对基本块结构、分支结构以及循环结构分别进行处理;

2-2)、如果当前执行的是基本块结构,将根据以下三种情况进行处理:

当遇到基本语句,将计算过程转换为一个代数表示,并生成一个代数表示节点作为当前基本块节点的子节点;

当遇到分支语句,转步骤2-3)生成一个分支节点作为当前基本块节点的子节点;

当遇到循环语句,转步骤2-4)生成一个循环节点作为当前基本块节点的子节点;

2-3)、如果当前执行的是分支结构,将分支条件作为一个路径约束,生成一个分支节点,分支结构的执行体是一个基本块,根据步骤2-2),生成一个基本块节点并将其作为当前分支节点的子节点;

2-4)、如果当前执行的是循环结构,将循环的计算过程抽象成为一个代数表示,并生成一个循环节点。

4.根据权利要求1所述的一种数值程序的全局优化方法,其特征在于所述的步骤1-3)中遍历原始程序的抽象语法树以及步骤1-2)生成的经过优化的代数表示形式,将代数表示形式对应的代码拼接到语法树节点中路径约束的提取位置合成所有代码片段,最终构成目标程序,具体过程如下:

4-1)、先序遍历抽象语法树,根据不同的语法树节点类型生成不同的代码片段,组合所有生成的代码片段最终生成目标程序;

4-2)、遇到代数表示节点,如果存在输入区间使得该代数表示的数值计算发生错误,则生成一个分支语句,分支条件记为C,它判断输入是否处于这个输入区间;如果C为真,将经过优化的代数表示转换为相应代码;否则,将原始的代数表示转换为相应代码;如果不存在这样的输入区间,则直接将原始的代数表示转换为相应代码;

4-3)、以下节点为结构节点,主要通过递归处理子节点来生成代码片段,根据结构节点的不同作不同处理,具体步骤为:当遇到基本块节点,递归处理它的子节点;

当遇到分支节点,生成一个分支语句,将该节点记录的路径约束转换成分支条件,递归处理该节点的子节点生成分支语句的执行体部分;

当遇到循环节点,将循环结构抽象出来的代数表示转换为相应代码。

说明书 :

一种数值程序的全局优化方法

技术领域

[0001] 本发明属于计算机数值计算与程序分析应用领域,涉及数值程序的全局优化技术,主要通过收集数值程序的全局计算过程而获得对应代数表示,并将其转换成数值误差累积更小的计算过程,以便生成相对原始数值程序更为准确,高效的优化程序。

背景技术

[0002] 根据IEEE745标准,单精度浮点数占用32个比特位,双精度浮点数占用64个比特位,尽管很多软件开发人员在开发程序时将它们看作实数值,但实际上它们能表示的数值是有限且不连续的。因此,对于大部分程序而言,浮点数会因为只能表示实数的近似值而不可避免地引入数值误差。在一个源程序中,可能涉及大量浮点数运算,这些浮点数运算的误差会随着程序的推进而累积,最终导致程序计算错误。
[0003] 为了避免这些数值计算错误,软件开发人员在编写数值计算程序前往往需要经过专业的数值分析培训,掌握许多数值分析的背景知识,并在编写相关程序时引入大量数值相关的细节操作。由于许多这样的细节操作与硬件平台相关,不仅非常繁琐,且极易出错,从而导致数值程序的主要逻辑被这些细节操作掩盖,降低了源代码的可读性,既不利于代码的正确开发,也不利于后续的代码维护。因此,本发明构建了一种数值程序的全局优化方法来解决这一问题。我们首先收集数值程序的全局计算过程,并而获得对应代数表示,并将其转换成数值误差累积更小的计算过程,以便生成相对原始数值程序更为准确,高效的优化程序。
[0004] 为了完成对数值程序计算过程的抽取,我们需要使用符号执行技术。符号执行技术最早由James King于1976年应用于系统测试领域。其主要思想在于用符号代替程序的具体输入值,然后按照程序逻辑在一定平台上进行模拟执行。在执行过程中,符号执行引擎会收集执行路径的路径约束。通过约束求解器对路径约束进行求解,可以生成覆盖各个执行路径的测试用例。在符号执行引擎现有基础上,我们将对其进行改进,从而完成对数值程序计算过程的抽取工作。

发明内容

[0005] 技术问题:本发明提出了一种数值程序的全局优化方法,它将原始数值程序自动地转化成计算逻辑相同但误差积累更小的优化数值程序。所述的数值程序的全局优化方法通过动态符号执行的方式抽取了程序返回值的符号表达式,同时通过数学代数变换的方式寻找等价且数值误差更小的表达式,将复杂的程序逻辑转换为对表达式的分析,从而实现对数值计算的全局优化。
[0006] 技术方案:本发明的一种数值程序的全局优化方法通过符号执行技术抽取关于数值程序计算过程的全局代数表示,不断寻找数值误差更小的代数表示,从而使得数值计算得到优化,具体步骤为:
[0007] 1-1)、利用符号执行技术动态执行原始数值程序,记录数值程序的结构信息、每条执行路径的路径约束条件以及计算过程的代数表示;
[0008] 1-2)、分别分析步骤1-1)收集的每个代数表示的全局形式,运用代数变换规则将原代数表示形式转换成数值计算误差更小的代数表示形式,再使用区间分析技术检验变换后代数形式的正确性,从而完成对每个代数表示形式的优化;
[0009] 1-3)、遍历原始程序的抽象语法树以及步骤1-2)生成的经过优化的代数表示形式,将代数表示形式对应的代码拼接到语法树节点中路径约束的提取位置(例如分支语句、循环语句),合成所有代码片段,最终构成目标程序。
[0010] 其中,
[0011] 步骤1-1)中利用符号执行技术动态执行原始数值程序,记录数值程序的结构信息、每条执行路径的路径约束条件以及计算过程的代数表示,它的输出是一棵抽象语法树;该抽象语法树只有四种节点,分别为代数表示节点,基本语句块节点,分支节点和循环节点;代数表示节点是数值程序计算过程的抽象,用于记录符号的代数表示;基本语句块节点用于表示数值程序的顺序结构,它的子节点可以由任意四种节点按序构成;分支节点用于表示数值程序的分支结构;循环节点用于抽象数值程序的循环结构,通过循环节点可以将循环的计算过程抽象成为一条累积求值表达式,整个抽象语法树抽象了数值程序的结构信息以及计算过程。抽象语法树的构造过程具体如下:
[0012] 2-1)、启动符号执行,初始化根节点为基本块节点,在执行过程中对基本块结构、分支结构以及循环结构分别进行处理(假设待处理数值程序的所有语法结构均可抽象为以上结构中的一种,对于其他的语法结构本发明不做处理)。
[0013] 2-2)、如果当前执行的是基本块结构,将根据以下三种情况进行处理:
[0014] 当遇到基本语句,将计算过程转换为一个代数表示,并生成一个代数表示节点作为当前基本块节点的子节点;
[0015] 当遇到分支语句,转步骤2-3)生成一个分支节点作为当前基本块节点的子节点;
[0016] 当遇到循环语句,转步骤2-4)生成一个循环节点作为当前基本块节点的子节点;
[0017] 2-3)、如果当前执行的是分支结构,将分支条件作为一个路径约束,生成一个分支节点,分支结构的执行体是一个基本块,根据步骤2-2),生成一个基本块节点并将其作为当前分支节点的子节点;
[0018] 2-4)、如果当前执行的是循环结构,将循环的计算过程抽象成为一个代数表示,并生成一个循环节点。
[0019] 所述的步骤1-2)中运用代数变换规则将原代数表示形式转换成数值计算误差更小的代数表示形式,具体过程如下:
[0020] 3-1)、初始化原始代数表示集合F;
[0021] 3-2)、对于F中的每个代数表示E,构建代数表示集合S={E};
[0022] 3-3)、用户任选一种配置好的选择策略(例如随机策略,机器学习、或者遗传算法策略),并按照该策略从S中选取一个代数表示Ei,并任选一种选择策略(可以与代数表示选择策略不同)从变换规则集中选取一个数学代数变换规则Ri,将Ri应用于Ei生成一个数学等价的代数表示Ei';
[0023] 3-4)、使用区间分析技术分析Ei'的误差区间是否扩大,如果没有扩大,则代数表示Ei'即为原始代数表示E的优化结果,将E从原始代数表示集合F中移除,跳转到步骤3-6);否则,执行步骤3-5);
[0024] 3-5)、将代数变换后的代数表示Ei'加入代数表示S,跳转回到步骤3-3);
[0025] 3-6)、判断原始代数表示集合F是否还存在待优化的代数表示,如果存在,跳转回到步骤3-2);否则,优化过程结束。
[0026] 步骤1-3)中遍历原始程序的抽象语法树以及步骤1-2)生成的经过优化的代数表示形式,将代数表示形式对应的代码拼接到语法树节点中路径约束的提取位置合成所有代码片段,最终构成目标程序,具体过程如下:
[0027] 4-1)、先序遍历抽象语法树,根据不同的语法树节点类型生成不同的代码片段,组合所有生成的代码片段最终生成目标程序;
[0028] 4-2)、遇到代数表示节点,如果存在输入区间(通过区间分析获得)使得该代数表示的数值计算发生错误,则生成一个分支语句,分支条件记为C,它判断输入是否处于这个输入区间;如果C为真,将经过优化的代数表示转换为相应代码;否则,将原始的代数表示转换为相应代码。如果不存在这样的输入区间,则直接将原始的代数表示转换为相应代码;
[0029] 4-3)、以下节点为结构节点,主要通过递归处理子节点来生成代码片段,根据结构节点的不同作不同处理,具体步骤为:
[0030] 当遇到基本块节点,递归处理它的子节点;
[0031] 当遇到分支节点,生成一个分支语句,将该节点记录的路径约束转换成分支条件,递归处理该节点的子节点生成分支语句的执行体部分;
[0032] 当遇到循环节点,将循环结构抽象出来的代数表示转换为相应代码。
[0033] 有益效果:本发明所述的数值程序的全局优化方法通过动态符号执行的方式抽取了程序返回值的符号表达式,同时通过数学代数变换的方式寻找等价且数值误差更小的表达式,将复杂的程序逻辑转换为对表达式的分析,从而实现对数值计算的全局优化。具体的有益效果体现为:
[0034] 1)、本发明可以将部分错误的数值计算程序转化为正确的数值计算程序。数值计算由于浮点数精度的限制可能会带来数值误差,而数值误差可能会由于程序的执行而进行累积,最终导致程序计算结果的错误。本发明在全局范围内对数值计算进行优化,寻找一种数值误差更小而又不改变原有程序逻辑的计算方式,从而将原来错误的程序转化为正确的数值计算程序。
[0035] 2)、对于一些对数值计算正确性有较高要求的程序,本发明可以提高它们的运行效率。为了确保数值计算的正确性,一些数值计算程序使用了高精度的自定义类型来进行数值计算,这会降低程序的运行效率。然而,如果使用本发明提出的全局优化技术,我们可以用低精度的浮点类型代替高精度的自定义类型来实现程序,然后通过工具将它们转化为数值计算误差更小的程序,既确保数值计算的正确性,又提高了运行效率。
[0036] 3)本发明可以提高数值计算程序的开发效率和可维护性。为了开发正确的数值计算程序,程序员需要使用一些特殊的技巧编写关于数值计算的代码,这不仅耗费时间,而且使得程序逻辑不直观,造成代码可读性下降,难以维护。通过本发明,程序员可以在实现过程中无需考虑数值计算的问题,只需将原有计算逻辑映射为对应的代码,既节约了开发时间,又提高了代码的可读性,使代码易于维护。为了解决数值计算正确性的问题,程序员可以通过工具将原有代码进行优化,从而减少数值计算的误差。

附图说明

[0037] 图1为数值计算全局优化的总流程。
[0038] 图2为代数表示抽取的流程。
[0039] 图3为代数表示优化的流程。
[0040] 图4为目标程序合成的流程。

具体实施方式

[0041] 本发明所提出的数值优化方法从全局的视角考虑数值计算,通过数学代数变换的方式将数值计算误差较大的代数表示转换成数值计算误差较小的代数表示,从而实现数值计算的误差优化。
[0042] 该方法通过符号执行技术抽取关于数值程序计算过程的全局代数表示,不断寻找数值误差更小的代数表示,从而使得数值计算得到优化,具体步骤为:
[0043] 1-1)、利用符号执行技术动态执行原始数值程序,记录数值程序的结构信息、每条执行路径的路径约束条件以及计算过程的代数表示;
[0044] 1-2)、分别分析步骤1-1)收集的每个代数表示的全局形式,运用代数变换规则将原代数表示形式优化成数值计算误差更小的代数表示形式,再使用区间分析技术检验变换后代数形式的正确性,从而完成对每个代数表示形式的优化;
[0045] 1-3)、遍历原始程序的抽象语法树以及步骤1-2)生成的经过优化的代数表示形式,将代数表示形式对应的代码拼接到语法树节点中路径约束的提取位置合成所有代码片段,最终构成目标程序。
[0046] 其中,
[0047] 所述步骤1-1)中利用符号执行技术动态执行原始数值程序,记录数值程序的结构信息、每条执行路径的路径约束条件以及计算过程的代数表示,它的输出是一棵抽象语法树;该抽象语法树只有四种节点,分别为代数表示节点,基本语句块节点,分支节点和循环节点;代数表示节点是数值程序计算过程的抽象,用于记录符号的代数表示;基本语句块节点用于表示数值程序的顺序结构,它的子节点可以由任意四种节点按序构成;分支节点用于表示数值程序的分支结构;循环节点用于抽象数值程序的循环结构,通过循环节点可以将循环的计算过程抽象成为一条累积求值表达式,整个抽象语法树抽象了数值程序的结构信息以及计算过程。
[0048] 所述的抽象语法树,其构造过程具体如下:
[0049] 2-1)、启动符号执行,初始化根节点为基本块节点,在执行过程中对基本块结构、分支结构以及循环结构分别进行处理;
[0050] 2-2)、如果当前执行的是基本块结构,将根据以下三种情况进行处理:
[0051] 当遇到基本语句,将计算过程转换为一个代数表示,并生成一个代数表示节点作为当前基本块节点的子节点;
[0052] 当遇到分支语句,转步骤2-3)生成一个分支节点作为当前基本块节点的子节点;
[0053] 当遇到循环语句,转步骤2-4)生成一个循环节点作为当前基本块节点的子节点;
[0054] 2-3)、如果当前执行的是分支结构,将分支条件作为一个路径约束,生成一个分支节点,分支结构的执行体是一个基本块,根据步骤2-2),生成一个基本块节点并将其作为当前分支节点的子节点;
[0055] 2-4)、如果当前执行的是循环结构,将循环的计算过程抽象成为一个代数表示,并生成一个循环节点。
[0056] 所述的步骤1-2)中运用代数变换规则将原代数表示形式转换成数值计算误差更小的代数表示形式,具体过程如下:
[0057] 3-1)、初始化原始代数表示集合F;
[0058] 3-2)、对于F中的每个代数表示E,构建代数表示集合S={E};
[0059] 3-3)、用户任选一种配置好的选择策略(例如随机策略,机器学习、或者遗传算法策略),并按照该策略从S中选取一个代数表示Ei,并任选一种选择策略(可以与代数表示选择策略不同)从变换规则集中选取一个数学代数变换规则Ri,将Ri应用于Ei生成一个数学等价的代数表示Ei';
[0060] 3-4)、使用区间分析技术分析Ei'的误差区间是否扩大,如果没有扩大,则代数表示Ei'即为原始代数表示E的优化结果,将E从原始代数表示集合F中移除,跳转到步骤3-6);否则,执行步骤3-5);
[0061] 3-5)、将代数变换后的代数表示Ei'加入代数表示S,跳转回到步骤3-3);
[0062] 3-6)、判断原始代数表示集合F是否还存在待优化的代数表示,如果存在,跳转回到步骤3-2);否则,优化过程结束。
[0063] 所述的步骤1-3)中遍历原始程序的抽象语法树以及步骤1-2)生成的经过优化的代数表示形式,将代数表示形式对应的代码拼接到语法树节点中路径约束的提取位置合成所有代码片段,最终构成目标程序,具体过程如下:
[0064] 4-1)、先序遍历抽象语法树,根据不同的语法树节点类型生成不同的代码片段,组合所有生成的代码片段最终生成目标程序;
[0065] 4-2)、遇到代数表示节点,如果存在输入区间使得该代数表示的数值计算发生错误,则生成一个分支语句,分支条件记为C,它判断输入是否处于这个输入区间;如果C为真,将经过优化的代数表示转换为相应代码;否则,将原始的代数表示转换为相应代码。如果不存在这样的输入区间,则直接将原始的代数表示转换为相应代码;
[0066] 4-3)、以下节点为结构节点,主要通过递归处理子节点来生成代码片段,根据结构节点的不同作不同处理,具体步骤为:
[0067] 当遇到基本块节点,递归处理它的子节点;
[0068] 当遇到分支节点,生成一个分支语句,将该节点记录的路径约束转换成分支条件,递归处理该节点的子节点生成分支语句的执行体部分;
[0069] 当遇到循环节点,将循环结构抽象出来的代数表示转换为相应代码。
[0070] 图1给出了该优化方法的具体流程,即首先通过符号执行技术抽取程序的结构信息、路径约束条件以及计算过程的代数表示。通过数学代数变换的方式寻找数值计算误差较小的代数表示,实现数值计算的全局优化。组合所有经过优化的代数表示,生成目标程序。以下部分就实施过程中的一些具体细节作更进一步的描述:
[0071] 一、循环抽象
[0072] 本发明优化数值计算的核心思想是使用代数变换规则将原有代数表示转换为数值计算误差更小的代数表示。可以使用的代数变换规则多种多样,其中有一类规则可以对诸如Σ、Π这种累积运算符进行优化。在传统符号执行过程中,符号执行引擎会将循环展开,因此我们得到的用于描述计算过程的代数表示也是展开的,而不是以Σ、Π这种累积运算符的形式体现。在这种情况下,我们无法充分利用上述的代数变换规则来对这个代数表示进行优化。因此,我们需要对循环进行一个抽象,把它转换成一个使用累积运算符进行描述的代数表示。
[0073] 循环抽象的过程可以通过静态分析技术完成。通过静态分析技术,我们可以将循环转换为一个抽象语法树,从而获得循环的结构信息以及语义信息。遍历抽象语法树,我们可以将循环执行一遍时的计算过程抽象成为一个代数表示E。再通过分析循环的执行次数,我们可以将代数表示E用Σ、Π等累积运算符组织起来,从而完成对循环计算过程的抽象。
[0074] 二、符号表达式选择策略和数学代数变换规则选择策略
[0075] 本发明主要通过数学代数变换的方式寻找数值计算误差更小的表达式。如图4所示,数学代数变换的过程如下:先使用特定策略从符号表达式集合中选取一个符号表达式E,然后使用特定策略从变换规则集合中选取一个变换规则R,将R应用于E生成一个等价的符号表达式E'。
[0076] 符号表达式选择策略P和变换规则选择策略Q是多种多样的,它们的选择也随着上下文的不同而有所不同。在无更多额外信息时,随机策略可作为P、Q的候选项。如果有更多的历史信息,遗传算法、机器学习、深度学习等不失为一种更好的选择策略。本发明并不限制使用何种选择策略,而是提供了一种数值程序全局优化的一种框架。在这个框架内,可以针对程序的特殊性选择最适合的策略,从而提高数值计算的优化效果。