专利名称:使用监控线程对二进制翻译程序执行流程动态监控的方法
技术领域:
本发明涉及一种使用监控线程对二进制翻译程序执行流程动态监控的方法, 用于获得二进制程序执行时的各种动态剖分信息,为分析二进制可执行代码程 序的执行流程和优化二进制翻译系统工作提供有效的支持。本发明属于并行化 计算和二进制翻译领域。
背景技术:
动态二进制翻译技术作为进程级虚拟机领域中重要的组成部分,在近年来的 计算机学术交流活动中,频频被提及和讨论。通常,动态二进制翻译技术采用
"两次翻译过程"和"缓存翻译后代码"的技术来提高性能。所谓两次翻译, 是指先从由源机器指令组成的源基本块,翻译为由系统自行描述的中间语言组 成的中间基本块,再由中间基本块翻译为目标机器上的可执行基本块。这种技 术的优点在于在不需要任何高级语言源代码信息的条件下,可以通过直接加 载源机器端的二进制可执行程序,并利用自身对不同机器指令集架构(ISA)的 翻译功能,得到目标机器端的可执行二进制程序。更重要的是,这种技术将翻 译和执行工作合并在一次程序过程中全部完成,有别于传统静态编译方法的先 编译后执行的二次过程。但是,动态二进制翻译系统的这种优势也为其获取程
序剖分信息(profile)带了很大的困难,即很难在动态执行的过程中保证获取完 备的剖分信息。而剖分信息正是用于程序执行流程监控的数据依据。
剖分信息(profile)是指那些在程序执行过程中,对程序性能起着重要影响 作用的信息。这些信息的获取,不仅可以用来判别程序编写的优劣,还能够为 优化工作提供量化的依据。在二进制程序中,程序是用以跳转指令或系统调用 结束的^^^:炎(Basic Block)为度量和划分的原子单位的,故完备的剖分信息就 包括每个基本块的执行次数;基本块间的跳转次数;分支预测的错误预测率;指令缓存、数据缓存的缺失命中率等。这些信息可以用来确定代码翻译的质量 和指导各种优化策略的有效实施。现有的统计这些剖分信息的方法包括插桩 (Instrumentation)禾卩采样(Sampling)两禾中技术。
*插桩(Instrumentation)这种方式通过在代码中插入探针指令来采集和程
序执行行为、特性有关的数据信息。这种方法借助软件实现,虽然硬件
成本较低,但是会引入额外的开销。 *采样(Sampling)这种方式以一定的时间间隔对程序运行的相关数据进
行数据收集,而不需要对程序进行修改,但是这种方法获得的剖分信息
具有一定的误差,而且需要借助硬件实现,成本较高。 在传统的动态二进制翻译系统中,为了节省硬件成本和降低系统对特定硬件 的依赖程度,通常选用插桩的方法进行剖分信息的收集,但是考虑到系统的性 能,仅插入了开销较小的、只能用来统计基本块执行次数的探针指令来完成热 路径的构建工作。所谓热路径,即当二进制程序中的某些基本块按照一定的顺 序频繁的被执行时,这样的程序路径被称为热路径。当这样的基本块或者路径 被检测出来时,通过将这条路径上的各个基本块整合在一起就可以加快程序的 执行速度,原因就在于减少了跳转指令执行的次数,这样不仅提高了指令缓存 的命中率,也提高了处理器流水工作机制的效率。为了获取更多的剖分信息使 超级块的构造更加有依据性,传统方法只能通过频繁的回调统计函数实现,而 该策略会使系统的执行效率变慢数十倍以上。(请参见文献Valgrind:A framework for heavyweight dynamic binary instrumentation, PLDI conference, 2007)。
随着多核处理器的不断发展,并行计算由于其更高的性能被越来越多的应用 在各种场景中,这主要归结于硬件级线程的概念,即不同的线程可以工作在不 同的CPU处理器核心上。在动态二进制翻译系统中,由于二进制程序收集剖分
信息的工作并不与原有动态二进制翻译系统"两次翻译"与执行的流程存在过 多的依赖,因此,可以尝试使用硬件级线程的方法来更高效地完成剖分信息获 取的工作。但是,这种思路在已有的国内外研究和实践工作领域中并未有类似 的实现案例。
发明内容
本发明的目的在于针对现有技术的不足,提供一种使用监控线程对二进制翻 译程序执行流程动态监控的方法,具有软件开销小,硬件成本低的优良特性, 能完整准确的获取监控信息,进一步提升动态二进制翻译系统的运行时性能。
为实现上述目的,本发明首先将原有动态二进制翻译系统执行流程作为主线 程,并为原有系统添加新的程序监控线程MT,然后为每一个翻译生成的基本块 插桩代码,使每个基本块执行时均将自身的入口地址写入队列中,队列溢出的 情况使用线程间等待的方式来避免。监控线程MT负责按序将各个入口地址取 出并查找对应的中间指令基本块,根据该基本块的结束类型更新线程MT中相 应的数据结构,完成程序监控的目的。最后,监控线程MT参照收集的剖分信 息,以决策者的身份完成热路径的构建优化。
本发明的使用监控线程对二进制翻译程序执行流程动态监控的方法具体实 现步骤如下
1、 本发明首先将原有动态二进制翻译系统执行流程作为主线程,并在原有 系统上新创建一条监控线程MT,用于完成对二进制程序执行行为的实时监视 工作。主线程和监控线程MT独立工作在多核处理器平台的不同核心上。
2、 借鉴传统插桩技术的原理,为每一个由动态二进制翻译生成的二进制基 本块的头部,插入一段机器代码,在执行该基本块的时候,这段机器代码负责 将这个基本块入的口地址存放入指定的队列Q中。当在这个过程中, 一旦该队 列Q被主线程中不断执行的基本块的入口地址填满时,为了保证监控的准确性和 程序的正确性,主线程必须暂停执行,等待监控线程MT处理完队列中的所有 数据后发出的再次启动信号Signal,当主线程收到该信号时,主线程才能继续 执行。
3、 监控线程MT依次从队列Q中获取基本块的入口地址,并通过査找该 入口地址对应的中间指令基本块,来了解该中间指令基本块具体的程序行为, 收集需要的各种剖分信息,并将结果存放于监控线程MT自建的数据结构中。 如果当该基本块入口地址存放的位置是队列Q的最大可存储位置时,监控线程MT将重新清空队列Q,并发送启动信号Signal通知主线程继续执行。
4、根据收集到的剖分信息,如果线程MT检测到某条程序路径执行的次数 大于某个设定的阈值时,监控线程MT将以决策者的身份,完成构建热路径的 优化过程。
5、对当前入口地址对应的基本块的剖分信息收集工作完成后,监控线程 MT将继续获取队列Q中下一个入口地址,重复步骤3和4中的操作,以达到对 二进制翻译程序执行流程动态监控的目的。
本发明与传统方法相比,具有软件开销小,硬件成本低,程序分析监控与程 序执行并行进行,获取的监控信息完整准确等多种优良特性,能够进一步地指 导动态二进制翻译系统的优化工作,提高其翻译代码的质量,降低其可执行代 码的分支预测错误率、缓存缺失率等影响性能的重要因素,因此这种方法能更 进一步提升动态二进制翻译系统的运行时性能。
具体实施例方式
为更好地理解本发明的技术方案,以下通过具体的实施例作进一步描述。以 下实施例不构成对本发明的限定。 1.创建硬件级监视线程MT
本发明实施例是基于上海交通大学自主开发的动态二进制翻译系统CrossBit (请参见文献:动态二进制翻译基础平台CrossBit的设计与实现,计算机工程, 2007.12 )之上研制的,CrossBit的执行流程为(1)加载源可执行映像;(2) 査找哈希表中是否存在由翻译后的目标机器码组成的基本块对象;(3)若查找 命中,执行对应的目标机器代码基本块;若查找缺失,则执行"由源机器码组 成的基本块->由中间指令组成的基本块->由目标机器代码组成的基本块"的基本 块两次翻译的过程,并将结果存入目标代码缓存中,更新哈希表,该表具有在 CrossBit中定位各基本块内存位置的功能。(4)执行目标代码基本块,如果遇到 跳转指令的目标地址不能确定或系统调用时,通过上下文切换(Context Switch) 回到CrossBit程序中,完成系统调用,或完成将跳转指令链接至新生成的目的 基本块的操作。最后程序流程跳回至流程(2)直到程序运行结束或发生异常。本发明将CrossBit原有的流程统一设置为一个主线程,将负责监控程序行为 的所有模块归结为另一个监视线程MT。线程的创建使用了 Linux下的pthread
程序函数库,艮P:
pthread一create(pthread一t pid, pthread—attr_t attr,void* fUnc(void*), void* arg);
其中,参数pid代表该线程在操作系统中的唯一标示,attr中包含该线程应有的 属性信息,func为该线程使用的代码函数实体,arg为其参数。
为了使主线程和监视线程MT具有硬件线程的特征,本发明使用Linux内核 宏函数CPU—SET将两个线程分别分配给不同的硬件处理器资源
CPU一SET( 0, &mask) //将主线程分配在多核处理器的0号核心上, CPU_SET( 1, &mask) //将监控线程MT分配在多核处理器的1号核心上。 2.插桩必要的代码
如果不采用硬件线程的方式而是传统方法来监控二进制程序的话,必然会使 用大量的插桩代码来完成应有的功能,导致程序执行时的效率较低。本发明借 鉴插桩技术的原理,结合硬件线程的特点,在每个经动态二进制翻译系统翻译 生成的基本块头部均插入如下一段机器代码,相对复杂的各种信息统计操作均 被安排在线程MT中完成,即变原有的串行剖分模式为一种并行剖分模式。
具体的插入的机器代码如下
%movw &QueueCount, %eax 〃将队列头指针值放入eax寄存器; %cmp 12M, %eax 〃比较头指针值与12M的大小关系,12M为多次实验后 确定的队列空间最大值;
%jle labell 〃小于等于12M跳至labell;
%movb 1, &overflow 〃否则设置队列溢出标志位变量overflow为1;
%ret 〃返回CrossBit主程序;
labell:
%add 4,%eax 〃label 1处首先将代表头指针的eax加4,因为每个EnterAddress
占据4个字节;
%movw %eax, &QueueCount 〃将新的头指针写回原头指针内存变量; %add &QueueEntry, %eax 〃计算实际存放位置,即头指针加上队列基地址;%movwEnterAddress, [%eax,0] 〃内存写操作,将基本块入口地址写入队列;
这段代码是一段在汇编语言级别进行队列操作的程序,该队列存在于程序进 程的虚拟内存空间中,故可以被主线程和监视线程MT共同访问。该队列的基 地址存放在变量QueueEntry中,而队列头指针变量QueueCount始终指向该队列 的队头位置,压入队列的操作就是将数据保存进QueueEntry+QueueCount标示的 内存位置中。标志位overflow用来通知CrossBit主程序发生了队列溢出行为, 即队列被基本块的入口地址填满的状态发生,此时主线程会调用pthread库中的 条件变量操作pthread_cond_wait(& pthread_cond_t)来等待监控线程MT重新清 空队列后发出的启动信号量。该系统调用会一直暂停主线程的执行,直到收到 对于该条件变量的signal操作pthread_cond_signal(& pthread—cond_t)的调用才 会继续主线程的执行。 3.监视线程MT的具体实现
监控线程MT依次从队列Q中获取基本块的入口地址,并通过查找该入口 地址对应的中间指令基本块,来了解该中间指令代码块的具体的程序行为,收 集需要的各种剖分信息,并将结果存放于监控线程MT自建的数据结构中。
当监控线程MT获取到一个基本块的入口地址时,它首先利用动态二进制翻 译系统中的哈希表函数查找得到该入口地址在"两次翻译"中对应的中间指令 基本块。由该中间指令基本块中的指令信息可以知道该基本块结束时的结束类 型,包括直接跳转、间接跳转、或是系统调用。硬件级监控线程MT负责对当 前执行的二进制程序的程序流程进行实时监控,为此该监控线程自建了三种数 据结构,分别为基本块执行次数表(用于统计直接跳转的目标基本块执行的次 数)、间接跳转表(用于统计间接跳转各边的跳转次数)、系统调用记录信息 表。由于主线程中每个入口地址是按程序执行的顺序依次被存入队列的,因此, 监控线程MT只需按先入先出(FIFO)的顺序依次读取,就可以了解程序执行 的内容和流程。同时,监控线程MT与主程序线程并行执行,这就可以较好的 保证监控的实时性。为了获取每个入口地址对应的基本块的语义,本发明利用 了 CrossBit中成熟的中间语言机制(请参考文献爿w /wfemjeife^丄awgwage ieve/0; rtVn/za,/ow尸ra附ewo ^》r Z)_y""m/c 5/war少7 "w^/""'(9W, Shi Huihui, Wang Yi, Guan Haibing, and Liang Alei, ACM SIG/PLAN Notice, vol-42(5), May 2007.)
举例说明,当监控线程MT取到的入口地址为0x40000000时(每个入口地 址为4字节,用于标示某代码块在整个进程空间中的位置),线程MT会首先 使用哈希函数找到该入口地址对应的中间语言组成的中间指令基本块,通过读 取中间指令基本块的最后一条指令,得到如下的三种结果之一.-
JMP (v25,0) 〃间接跳转;
BRANCH (tttn,v21 ,v22, v0, disp) 〃直接跳转,tttn为条件码,v0==0 , v21 , v22中存放需要比较的两个操作数,即当v21和v22满足tttn指定的跳转条件时, 程序跳至(0+disp)指定的目标地址。
SYSCALL 〃系统调用;
其中的JMP指令由于使用了虚拟寄存器v25作为基地址寻址,而偏移量为0, 故该条指令为间接跳转,当读到下一个入口地址为0x50000000时,线程MT就 在间接跳转表中增添记录(0x40000000, 0x50000000, 1),即表示从0x4000000 基本块向0x50000000基本块的间接跳转被执行了一次。对于直接跳转和系统调 用进行的操作类似,不同的仅为更新的具体的数据结构的不同。
在上述流程中,本发明各表均由C十+标准库STL提供的数据结构实现。
当监控线程MT发现其正在处理的入口地址的当前存放位置是队列的最大 可存储位置时,监控线程MT需要将队列重新置位。方法为设置现有的 QueueCount变量为0,即下次主线程将重新从队列起始位置保存新的入口地址。 另外,监控线程MT还需要调用pthread库中的pthread_cond—signal (&pthreacLcondJ)函数完成启动信号的发送。 4.监视线程MT的决策功能实现
监控线程MT进行程序监控的目的,就在于获取完善的剖分信息和分析二进 制程序的执行流程。而当剖分信息满足一定条件时,本发明可以启动一些特定 的优化方法,常用的方法为热路径的构建。
因此,本发明的监控线程MT当检测到某个直接跳转的基本块的执行次数大 于阈值3000或某条间接跳转的执行次数大于阈值5000时(这些阈值通过反复实验确定),就完成相应的优化工作,包括基于直接跳转检测完成的超级块构建
过程,和基于间接跳转检测完成的超级块构建过程,从而使原有的动态二进制
系统的执行速度加快。
5.监控线程MT工作模式的设计
完整的监控线程MT采用了 while轮询结构进行设计,而并非常见的通过互 斥信号量(Mutex)实现的消费者/生产者关系模型。轮询架构尽管会占用大量的 处理器时间,但是具有更好的实时并行效果,加之监控线程MT被实现为硬件 线程,其处理器时间的浪费并不影响主程序的执行效率,故被本发明采用。因 此,当队列Q不为空时(即QueueCount 〉 0时),线程MT将不停地循环读取 下一个入口地址并进行处理。
如此,实现对二进制翻译程序执行流程的动态监控。
权利要求
1、一种使用监控线程对二进制翻译程序执行流程动态监控的方法,其特征在于包括如下步骤1)将原有动态二进制翻译系统执行流程作为主线程,并在原有系统上新创建一条监控线程MT,用于完成对二进制程序执行行为的实时监视工作;主线程和监控线程MT独立工作在多核处理器平台的不同核心上;2)借鉴传统插桩技术的原理,为每一个经动态二进制翻译系统翻译生成的二进制基本块头,插入一段机器代码,在执行该基本块的时候,这段机器代码负责将该基本块的入口地址写入队列Q中;在此写入过程中,一旦队列Q被填满,主线程必须暂停,等待监控线程MT处理完队列中的所有数据后发出的再次启动信号Signal,当主线程收到该再次启动信号时才能继续执行;3)监控线程MT依次从队列Q中获取基本块的入口地址,并通过查找该入口地址对应的中间指令基本块,来了解该中间指令基本块具体的程序行为,收集需要的各种剖分信息,并将结果存放于监控线程MT自建的数据结构中;如果当该基本块入口地址存放的位置是队列Q的最大可存储位置时,监控线程MT将清空队列Q,并发送再次启动信号Signal通知主线程继续进行;4)根据收集到的剖分信息,如果监控线程MT检测到某条程序路径执行的次数大于设定的阈值时,监控线程MT将以决策者的身份,完成构建热路径的优化过程;5)对当前入口地址对应的基本块的剖分信息收集工作完成后,监控线程MT将继续获取队列Q中下一个入口地址,重复步骤3)、4)中的操作,以实现对二进制翻译程序执行流程的动态监控。
全文摘要
本发明提出了一种使用监控线程对二进制翻译程序执行流程动态监控的方法。首先为原有动态二进制翻译系统创建新的程序监控线程MT,然后为每一个翻译生成的基本块插桩代码,使每个基本块执行时均将自身的入口地址写入队列中,队列溢出的情况使用线程间等待的方式来避免。监控线程MT负责按序将各个入口地址取出并查找对应的中间指令基本块,根据该基本块的结束类型更新相应的数据结构,完成程序监控的目的。最后,监控线程MT参照收集的剖分信息,以决策者的身份完成构建热路径的优化。与传统的程序监控方法相比,本发明具有软件开销小,硬件成本低,程序分析监控与程序执行并行进行,获取的监控信息完整准确等多种优良特性。
文档编号G06F9/45GK101593125SQ20091005432
公开日2009年12月2日 申请日期2009年7月2日 优先权日2009年7月2日
发明者倪志晨, 李晓龙, 梁阿磊, 管海兵, 邓海鹏 申请人:上海交通大学