多处理器计算机上的java线程同步的灵活加速的制作方法

文档序号:6428187阅读:175来源:国知局
专利名称:多处理器计算机上的java线程同步的灵活加速的制作方法
技术领域
本发明涉及用于提高Java线程同步的性能的软件和硬件方法。
背景技术
运行在服务器、甚至高端工作站上的Java软件必须被设计为允许由大量CPU(中央处理单元)来执行。Java通常以线程执行。线程是运行在程序内的单个串行控制流。线程也被称为执行上下文或轻量级进程。可以同时运行多个线程。线程将共享资源,例如全局数据、存储器、代码的临界部分、以及其它资源。所共享的资源具有相关的“锁”。为了访问资源,线程必须获得该资源的锁。
制约性能的主要瓶颈就是如何实现多线程对同一共享资源的访问的“锁定”或同步。在Java程序中,广为使用的访问控制是“监控器”结构。软件实现的底层Java虚拟机(JVM)为Java程序提供了运行时间环境,并负责实现所需要的锁定机制。根据JVM所采用的实现方法和平台中对同步原语的硬件支持,运行在多处理器服务器上的企业级电子商务Java软件可能存在着各种各样的性能。
在大多数处理器中实施的、用于同步的常用硬件技术是由执行诸如“XCHG”一类的指令而引起的原子性读-修改-写总线周期。在对锁(因此,对这些锁所保护的资源)的争用很激烈的环境中,多个CPU在尝试确保同一个锁或同一组锁的所有权时,可以同时执行锁定的读-修改-写操作。这被称为“惊群(thundering herd)”问题,它导致激烈的系统总线争用。因此,多处理器的可扩展性受到了限制。结果,带来严重的性能损失。
在下面的表1中给出了用于解释这个问题的样本代码。
1 //available.If it is 1,another process is in the critical section.
2 //
3 spin_lock4mov ar.ccv=0 //cmpxchg looks for avail(0)5mov r2=1 //cmpxchg sets to held(1)6 spin7ld8 41=[lock];;//get lock in shared state8cmp.nep1,p0=Ref.1,r2 //is lock held(ie.Lock==9 1)?10 (p1) br.cond.spnt spin;; //yes,continue spinning1112 cmpxchg8.arqrl=[lock],r2;; //attempt to grab lock13 cmp.ne p1,p0=Ref.1,r2//was lock empty?14 (p1) br.cond.spnt spin;; //bummer,continue spinning15 cs_begin16 //critical section code goes here...
17 cs_end18 st8.rel[lock]=r0;; //release the lock表1在第4行,进程cmpxchg指令寻找可用的锁。在第5行,如果找到了可用的锁,则该锁的状态从0变到1。在第9行,有一次夺取锁的尝试。在第10行询问该锁是否为空并在第11行给出了答案,在第11行,获取锁的尝试不成功,并且进程必须继续,直到它发现资源未锁定。希望最小化与锁争用有关的开销。


结合附图,在以下描述中以示例的方式解释了本发明。
在附图中图1是本发明中所使用的软件数据结构元素的图,其用于监控和锁的争用有关的动态性能分析(dynamic profiling)信息;图2和3是图示了在Java虚拟机中关于锁争用的动态性能分析的流程图;以及图4是根据本发明用于提供同步加速的硬件的框图。
具体实施例方式
由于现有技术中的JVM或等同的运行时环境在Java程序和该程序运行于其上的平台之间扮演着“中间人”的角色,所以它们处在一个独特的位置上。所述平台包括操作系统和硬件。许多JVM包括带有自适应编译技术的即时(just-in-time)编译器,其被用来优化程序在其上花去大多数时间的代码。图1是监控器数据结构的图。
“监控器”是一种用于控制对共享资源的访问的技术。监控器本质上是一个具有显式队列的共享类。通过例如创建一个其中所有字段都是私有的,并且所有方法都同步的类,就可以在Java中实现共享类的作用。唯一可被一个以上的线程访问的变量是监控器的字段。监控器的方法被同步。因此,监控器中的访问是相互排斥的。因此,监控器将满足提供对线程的互斥访问的要求。本发明的一个特点就是提供了收集有关锁的争用的动态性能分析信息的能力。为此,向监控器数据结构10附加了扩展字段14。
Java的“监控器”方法支持两种线程同步互斥和合作。在Java虚拟机中通过对象锁来支持的互斥使得多个线程独立于共享数据地工作,而不相互干扰。在Java虚拟机中通过“等待”和“修改”方法来支持的合作使得线程一起工作,以达到共同的目标。本说明书处于互斥的上下文中。
一个线程每次可以获取一个监控器。在JVM的软件中,扩展字段14被附加到监控器数据结构10。典型的监控器数据结构大到足以使得增加少量位不会导致存储器使用的大量增加,也不会对JVM的性能产生负面作用。这个扩展字段14向JVM提供以下知识,即哪个Java线程请求获得对给定监控器的所有权。线程获得使用对象的权利,然后在完成时释放锁/监控器。当它再次需要使用对象时,它再次获得锁,然后在完成时再次释放锁,如此等等。JVM使用扩展字段来对不同线程在给定时间段内对监控器的不同访问保持“计数”。如果大量线程在短时间内尝试得到监控器的所有权,则计数值将会是一个很大的数,并将锁标识为“热”锁,即高度争用的锁。如果监控器主要由单个线程进行访问,则所述计数值将是“1”,并且锁是“冷”锁。
一旦JVM确定哪些锁是“热的”,则它可以选择将要用于这组锁的最适当的同步技术。JVM设置争用的阈值。这个阈值与实际的计数值做比较。如果计数值超过了指定来标识热锁的阈值,则JVM确定对这些热锁使用硬件加速技术。图2图示了其中对给定的锁争用较低的例子中的过程。在图2中,在框20处,线程请求监控器。在框22处,确定请求线程与以前请求监控器的线程是否不同。如果相同,则不采取任何对特定的监控器增加访问计数的动作,并且这个过程返回到框20。如果与以前的线程不同的线程正在争用锁,则在框24处增加该监控器的访问计数。
图3表示将每个访问计数与指示热锁的阈值进行比较的过程。在框30处,监控器计数与阈值进行比较。在框32处,如果该计数没有超过阈值,则不对特定的锁采取任何进一步的动作,并且该过程返回框30。如果在框24达到的计数值的确超过了阈值,那么操作前进到框34,在这里向热锁列表中添加锁。图2和3的过程可以在JVM或硬件中实现。因此,提供了对热锁的标识。
返回上述表1中的现有技术的进程中,可以看出,这个进程固有地提供了大量争用。争用是由于缺乏一个中央实体而引起的,所述中央实体可以登记(register)多个处理器对锁的请求,还可以裁决对锁的分配。因此,处理器必须反复地尝试获得锁。如果存在中央实体,就可以大大减少读-修改-写周期的数量,其中,从所需的额外步骤和额外时间、或者开销的角度来看,这种读-修改-写周期是很昂贵的。在图4中图示了提供中央实体的硬件,这是一个4-CPU基于总线的配置的框图。这里提出一种4-CPU配置,并提供了对本发明具体实施例的图示。但是,也可以使用其它数量的CPU。所图示的结构是可扩展的。4个CPU被排列为与前侧总线相连。可以提供其它配置。
在图4中,所提及的4个CPU是40、42、44和46。它们每一个都和数据总线50通信,而数据总线50也和芯片集52通信。它还包括耦合到存储器56的主机存储器控制器54。所图示的四个锁58-1到58-4用于展示对访问存储器56的控制。存储器56是一个共享资源。
也位于芯片集52上的还有锁登记单元60。虽然并非一定要在芯片集52上提供锁登记单元60,但它是优选的。在本实施例中,锁登记单元60包括四个锁寄存器64。为方便起见,图示了四个锁寄存器64。在名义(nominal)应用程序中的寄存器的数量一般要高得多。然而,为了便于解释,对锁寄存器64的数量进行了限制。锁寄存器64的数量是平台相关的。在初始化时,锁寄存器的数量被通知给JVM。JVM对硬件加速的使用被限制为可用的锁寄存器的数量。如果没有可用的锁寄存器64,则JVM用软件来管理同步。
通过对在硬件或软件中是否有更多的锁寄存器64这一配置提供一定的灵活性,设计者就有机会在性能和成本之间实现平衡。在本发明中,为四个锁中的每一个都提供一个锁寄存器64。这些锁被标识为锁58-1、58-2、58-3和58-4。每个锁寄存器64都包括一个计数器,用于登记对各个锁58的CPU锁请求。锁登记单元60还包括一个裁决器68,它将选择一个CPU给予其对锁的访问权。当前被给予对锁的访问权的CPU被称为“胜利者”。向当前的“失败者”CPU提供一个旋转(spin)标志,让它们继续旋转以再次请求访问权。一旦胜利者CPU释放了锁,则锁登记单元60通过裁决器68选择下一个胜利者,并且只要还有未决的请求,上述过程就重复进行。
锁寄存器计数器64登记CPU锁请求。对应于每个锁寄存器64包括一个所有权寄存器66,其登记了由锁号、线程号、CPU号和旋转标志所标识的当前锁所有权。锁寄存器66存储线程ID,因为一旦已经指定硬件锁,则JVM必须保证线程在锁请求和锁释放之间不会迁移到不同的CPU。通过使用标准的操作系统呼叫来请求线程结合绑定(affinity-binding),就可以防止迁移的发生。
一种可替换的实现方案(虽然可能不那么理想)将不需要所述结合,但是当线程将从一个CPU迁移到另一个时,必须更新已存档的CPU号,并发出单独的旋转标志。
锁登记单元60可以使用简单的循环(round-robin)裁决来在多个请求间做出裁决。这种技术可应用于其它裁决模型,例如基于优先权的裁决。
如以下例子所示,非常希望提供旋转标志。如果CPU 44请求一个特定的锁62,但是在裁决中失败,而CPU 40具有所有权,在传统的现有技术模型中,CPU 44将继续旋转(等待一会儿),然后再次尝试。CPU也可以称为处理器。通过发出读-修改-写而再次进行尝试。如上所述,这是将导致总线争用和性能问题的动作。在本发明中,当锁登记单元60确定CPU 44应当得到特定的锁62的所有权时,起到中央实体作用的锁登记单元60将向CPU 44提供通知。
这个操作如下进行当CPU 44“失败”时,它受可缓存的存储器中的特殊标志的影响而旋转;在第一次访问后,读将是来自该CPU的缓存,并且不会产生总线流量;以及当CPU 44被认为获得所有权时,寄存器单元60在其存储器中写标志变量,并在处理器总线50上发出侦听(snoop)总线周期。
所述侦听值使标志值无效,并且CPU 44发出读周期,以从存储器56得到新的值。新的值使得CPU 44脱离旋转循环并进入其临界部分。旋转标志地址值由JVM编程在芯片集中,或者由代表JVM的芯片集驱动器来编程。所述驱动器需要完成从虚拟地址到物理地址的翻译,从而得到对应于特定线程的旋转标志的物理地址。
应当注意对锁争用的动态性能分析和性能分析数据的使用,以在各种意义下对所选择的同步技术进行选择和调节。它们可以用硬件以及软件来实现。
以上方法可以由机器可读介质来执行。机器可读介质包括提供(即,存储和/或发送)机器(例如计算机)可读形式的信息的任何机制。例如,机器可读介质包括只读存储器(ROM)、随机访问存储器(RAM)、磁盘存储介质、光存储介质、闪存设备、以及电、光、声或其它形式的传播信号(例如,载波、红外信号、数字信号或其它形式的信号)。
这样就提供了一种用于锁争用的动态性能分析的方法和装置,一种使用性能分析数据来选择并选出所使用的同步技术的方法和装置,以及与所述动态性能分析和同步技术的选择交互的、与平台相关的同步加速硬件。上述说明书将使得本领域的技术人员能够对以上所描述的特定例子做出多种修改,以提供与本发明一致的多种方法和装置。
权利要求
1.一种方法,包括使用监控器来控制竞争线程对共享资源的访问,所述监控器具有用于处理锁请求的数据结构;在所述监控器数据结构中提供扩展,以对给定的时间段内不同的线程访问进行计数;以及登记争用线程对给定的锁的多个不同请求,并且登记一个计数,其表示在给定的时间段内争用线程的数量。
2.如权利要求1所述的方法,其中,产生争用线程的计数包括感知对监控器的线程请求,确定所述发出请求的线程是否与以前发出请求的线程不同,并且响应于一种比较结果,增加指示争用的监控器访问计数,其中该比较结果指示了发出请求的线程不同于以前发出请求的线程。
3.如权利要求2所述的方法,包括比较所述监控器访问计数和阈值,确定所述计数何时超过阈值,并且响应于超过所述阈值的所述计数,将锁标识为“正被高度争用”。
4.如权利要求3所述的方法,还包括通过根据所选择的方法选择一个对被高度争用的锁的锁请求,从而对将锁标识为“正被高度争用”做出响应。
5.如权利要求4所述的方法,其中,使用硬件加速来处理锁请求包括预选择数量的处理器中的每一个都发出对共享资源的给定的锁的请求,在多个请求中做出裁决,通知当前胜利者处理器,并且提供访问权;向没有得到访问权的处理器发出可缓存的存储器中的特殊的标志变量,修改存储器中的该标志变量,以在先前处理器释放它的锁时,将访问权给予原来没有得到访问权的处理器。
6.一种提供指令的机器可读介质,所述指令在由处理器执行时使得所述处理器执行操作,所述操作包括使用监控器来控制竞争线程对共享资源的访问,所述监控器具有用于处理锁请求的数据结构;在所述监控器数据结构中提供扩展,以对给定的时间段内的不同的线程访问进行计数;以及登记争用线程对给定的锁的多个不同请求,并且登记一个计数,其表示在给定的时间段内争用线程的数量。
7.如权利要求6所述的机器可读介质,其中,登记争用线程的计数的指令包括感知对监控器的线程请求,确定所述发出请求的线程是否与以前发出请求的线程不同,并且响应于一种比较结果,增加指示争用的监控器访问计数,其中该比较结果指示了发出请求的线程不同于以前发出请求的线程。
8.如权利要求7所述的机器可读介质,包括以下指令比较所述监控器访问计数和阈值,确定所述计数何时超过阈值,并且响应于超过所述阈值的所述计数,将锁标识为“正被高度争用”。
9.如权利要求8所述的机器可读介质,还包括以下指令通过根据所选择的方法选择一个对被高度争用的锁的锁请求,对将锁标识为“正被高度争用”做出响应。
10.如权利要求6所述的机器可读介质,其中,使用硬件加速来处理锁请求的指令包括预选择数量的处理器中的每一个都发出对共享资源的给定的锁的请求,在多个请求中做出裁决,通知当前胜利者处理器,并且提供访问权;对于没有获得访问权的处理器,在可缓存的存储器中增加一个特殊的标志变量,修改存储器中的标志变量,以在先前处理器释放它的锁时,将访问权给予原来没有得到访问权的处理器。
11.如权利要求10所述的机器可读介质,其中,所述机器可读介质是Java虚拟机。
12.一种锁寄存器,包括处理器锁寄存器,用于登记多个处理器中的每一个处理器对共享资源的访问请求,还包括与所述锁中每一个相对应的锁“当前所有权”数据结构,所述锁数据结构登记所述锁的标识、争用线程的标识和所述线程正在其上执行的处理器的标识。
13.如权利要求12所述的锁寄存器,还包括旋转标志字段,所述锁寄存器还包括裁决器,用于选择一个处理器来访问锁,并且向未获得对所述锁的连接的争用处理器发出旋转标志。
14.如权利要求13所述的锁寄存器,其中,向所述未获得访问权的处理器发出旋转标志还包括在前面的处理器放弃对锁的控制时,指定争用处理器对于连接的访问优先权。
15.如权利要求14所述的锁寄存器,包括寄存器字段,用于感知何时没有可用的寄存器。
全文摘要
本发明提供了一种方法和机器可读介质,用于测量线程对锁的请求,以根据对所述锁的争用程度来区分“热”锁和“冷”锁。一种硬件加速器管理对热锁的访问,以提高性能。
文档编号G06F9/52GK1630852SQ02819238
公开日2005年6月22日 申请日期2002年9月27日 优先权日2001年9月28日
发明者迪普·K·布什 申请人:英特尔公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1