续操作将予删除,实现代码精简。
[0062]在一个示例中,根据数据依赖迭代式计算和该切片起点直接相关的变量和语句包括:根据不同读写函数的定义,将相关调用参数变量加入相应的初始相关变量集合,主要包括两种:1)将读写操作的数据内容变量(一般是缓冲区变量)作为无关变量,后续计算依赖时只保留相关声明、指针赋值等相关操作即可;以及2)将其它所有变量视为读写行为控制变量,即视为影响输入输出行为的参数,加入初始相关变量集合。
[0063]在一个示例中,迭代式计算所有直接相关的变量和语句。直接相关是通过数据依赖分析完成。例如语句i中为了计算某已知相关的变量使用了另一变量V的值,计算变量V值的语句j如果可以直接跳转到语句i,那么视为语句j也为相关语句,并且该语句中使用的所有其他变量也都视为相关变量。
[0064]在一个示例中,考虑语句之间的控制依赖,主要包括条件分支语句if或者for, while循环语句等,计算所有间接相关的变量和语句。控制依赖主要用于分析计算分支条件本身所需要变量是否相关。
[0065]关于通信依赖,通信依赖是并行程序的固有特性,高性能程序往往采用MPI通信模型在不同进程间显式交换数据。因此,可以从源码级别进行一定程度的通信分析。例如点对点通信的发送和接收进程通常在程序中成对出现。通信依赖可以通过识别程序中所有可能匹配的计算操作来计算。在一个示例中,本发明实施例采用比较保守的策略,其中根据参数的类型和作用范围,尽量保留所有可能相关的语句,以保证生成程序的正确性。本发明不限定使用的通信依赖具体实现方法。
[0066]在步骤S1400中,基于得到的各个静态程序切片生成精简代码。
[0067]在一个示例中,基于得到的各个静态程序切片生成精简代码包括:记录切片后要删除的语句行号信息;基于所记录的切片后要删除的语句行号信息,从原始应用程序源代码中删除所述要删除的语句行号信息所指示的语句。
[0068]在一个示例中,为了获得要保留的相关语句在源程序中的位置和行号信息,从所有切片相关语句(中间代码格式)的元信息中收集该语句在原始代码中的文件路径、文件名和代码行号等信息。
[0069]在一个示例中,基于得到的各个静态程序切片生成精简代码还包括:从原始应用程序源代码中识别并删除对应无关的计算和通信操作的语句。
[0070]在一个示例中,为保证精简后代码可以直接编译、运行,所述生成精简代码的步骤还包括处理精简源代码中各种兼容的语法、条件表达式、函数调用等语句。这一部分可以借助编译器的前段分析工具辅助完成。
[0071]在一个示例中,所述基于得到的各个静态程序切片生成精简代码包括在生成精简代码过程中进行插粧操作,由此能够在该存储系统基准评测程序被执行时统计读写操作次数、数据块大小、所需时间信息,从而生成读写带宽信息。通过所述插粧操作,在精简的评测程序的源代码中增加额外的语句,记录输入输出操作的相关信息,比如数据块大小、迭代次数和时间等,并在程序最后进行统计读写带宽。这样,用户采用精简后的程序作为评测程序使用时,可直接获得直观的存储系统性能报告。
[0072]输入输出操作与计算和通信重叠的情况在一些应用程序中存在。如果简单地删除计算或通信声明语句,可能会减少或者删除两个连续操作间的间隔。这种情况下响应连续的输入输出请求,存储系统可能会表现出比原始应用程序较差的性能。为此,优选地,在S1400步骤中,标记原始程序中被全部删除的、不包含任何输入输出相关语句的循环块,并在代码删除时插入休眠语句sleep (time)模拟计算的执行。考虑到基准程序的源代码完全可用并且远比原始应用程序紧凑,整个代码精简过程结束后,程序的开发者可以在精简程序中,手动决定睡眠间隔time。
[0073]在一个示例中,图1所示实施例的存储系统基准评测程序生成方法还可以包括对生成的精简程序进行正确性验证的步骤,包括:获得精简代码和原始程序在相同问题规模下的执行踪迹文件;对比精简代码和原始程序在相同问题规模下的执行踪迹文件,确定两者之间输入输出行为之间是否不同,当确定两者之前输入输出行为一致时,确定精简代码是正确的。当精简程序运行时表现出和原始应用程序一致的输入输出特征时,即可投入使用,代替原始程序进行存储系统性能评测。图2示出了上述精简程序正确性验证的示例性过程的示意图,如图2所示,纸面左侧,高性能应用程序(即原始程序)通过插粧工具插粧,然后执行,得到执行踪迹;右侧,对应的精简评测程序执行,得到执行踪迹,然后比较两者的执行踪迹看是否一致,从而得出精简评测程序是否正确的评估结果。
[0074]附图1中的静态切片分析操作和精简代码生成步骤可以在目前的主流编译器中实现,例如LLVM、GCC和0pen64。在一个优选示例中,采用LLVM编译器。本实施例采用自底向上的、静态分析方式的、基于数据流方程的切片计算方法。具体的数据流方程可采用业界主流做法或任何未来出现的适当的数据流方程,此非本发明关注焦点,为避免混淆要点,这里不做详细讨论。
[0075]图3示出了一个对应用程序进行切片从而生成精简程序的例子,用来阐明原始应用程序和切片后的精简程序间的不同。为了方便对比,此处没有展示统计输入输出的插粧代码。
[0076]如图3所示,原始应用程序是字符串变换和搜索,主要任务是进行字符串的变化,最后统计固定迭代步后得到的字符串中,某一字符的出现次数。其中每一步中间字符串都会存储起来以便故障恢复。这个程序是数据并行性比较好的程序,不同进程之间按照数据范围进行分割,每个进程都在字符串变换后,负责调MPI读写例程MPI_File_write_at_all将缓冲区的字符串写入到共享文件中的固定偏移位置。进程写入的文件偏移量范围没有重叠,是弱扩展的程序。这个程序受生物计算中的基因对匹配程序的启发,是一个样例程序。
[0077]为了收集和输入输出相关的语句,首先需要标示和输入输出直接相关的语句(图3中下划线的语句),这可以通过识别固定的MPI或者POSIX接口的函数调用完成。其次,程序切片工具会分析这些语句依赖的其他语句,并迭代式寻找新的依赖。
[0078]依赖的语句可能是数据依赖,即相关语句需要用到某一个变量的值,那么该值所有的计算语句都被识别为新的相关语句。例如48行的输出操作依赖47行对disp变量的计算。依赖也可能是控制依赖,例如第38行语句的执行依赖第37行的条件分支。最后,依赖还可能是通信依赖,例如48行的操作依赖第39行的广播通信。
[0079]经过程序切片,所有与输入输出相关的语句会被保留下来,剩下的无关语句会被删除。其中图2中,带删除线的程序语句即表示和输入输出不相关的语句,在精简程序中都被删除。对比原始程序和精简程序的源代码,可以发现二者的不同:
[0080].函数transform中所有语句和main函数中45行的调用点全被删除。通过分析可知,这些计算和该程序的输入输出行为无关,因此可以删除。删除后的程序仍然可编译,是独立、完整的程序代码。若第45行没有被删除,可能会引发编译或者运行时错误。需要指出,函数transform中的临时变量的内存分配因为和输入输出无关,也可以直接删除。标准库调用sqrt也因此删除,减少了无关的计算。
[0081].20行到