具体实施方式
提供下述说明,使得本领域技术人员能够制造并使用本发明,下述说明陈述了发明人想到的执行其发明的最佳模式。然而,当考虑到此处限定的本发明的整体原理时,各种修改对于本领域技术人员仍然容易地显而易见。
图1给出了其中可应用本发明的实施例的***和环境的概览,以便介绍将在下面更详细地讨论的组件、模块和单元。参照图1,主题程序17应在具有至少主题处理器3的主题计算***1上执行。然而,代替地使用目标计算***10,通过执行程序代码变换的翻译器单元19来执行主题程序17。翻译器单元19执行从主题代码17到目标代码21的代码变换,从而目标代码21可在目标计算***10上执行。
如同本领域技术人员熟知的,主题处理器3具有一组主题寄存器5、主题存储器8在其它事物中保持主题代码17和主题操作***2。相似地,图1中的示例目标计算***10包括至少一个具有多个目标寄存器15的一个目标处理器13;和存储包括目标操作***20的多个可操作组件、主题代码17、翻译代码19和翻译目标代码21的存储器18。目标计算***10典型地为基于微处理器的计算机或其它适合的计算机。
在一个实施例中,翻译代码19是利用或不利用最优化,将主题指令集架构(ISA)的主题代码翻译为另一个ISA的翻译目标代码的仿真器。在另一个实施例中,翻译器19的功能是通过执行程序代码最优化将主题代码翻译成目标代码的加速器,主体代码和目标代码都是相同的ISA的。
翻译代码19适宜地是实现翻译器的源代码的编译版本,并且与操作***20相结合地在目标处理器3上运行。应认为,图1示出的结构仅是示例性的,并且可以存留在操作***20之内或之下的代码来实现例如根据本发明的实施例的软件、方法和处理。存储器18的主题代码17、翻译代码19、操作***20和存储机制可以是本领域技术人员已知的各种类型。
在根据图1的设备中,动态地在运行时执行程序代码变换,以在运行目标代码21的同时在目标架构10上执行。也就是说,翻译器19是根据翻译目标代码21运行的。通过翻译器19运行主题程序17涉及以交替形式执行的两种不同类型的代码:翻译代码19;和目标代码21。因此,目标代码21是基于被翻译的程序中的存储的主题代码17,在运行时由翻译代码19产生的。
在一个实施例中,翻译器单元19仿真诸如主题处理器3和特别是主题检测器5的主题架构1的相关部分,同时在目标处理器13上实际执行作为目标代码21的主题程序17。在优选的实施例中,提供至少一个全局检测器组(global register store)27(也称为主题寄存器库27或抽象寄存器库27)。在多处理器环境中,根据主题处理器的架构提供了可选择的多于一个的抽象寄存器库27。通过翻译器19和目标代码21的组件提供主题状态的表示。也就是说,翻译器19在各种具体编程语言装置中存储诸如变量和/或对象的主题状态。通过比较,翻译目标代码21在目标寄存器15和由目标代码21的目标指令操纵的存储位置18中隐含地提供主题处理器状态。例如,全局寄存器组27的低层表示仅为所分配的存储器的一个区域。然而,在翻译器19的源代码中,全局寄存器组27是可在较高层访问和操纵的数据阵列或对象。
术语“基本块”对于本领域技术人员是熟知的。基本块是恰好具有一个入口点和恰好一个出口点的一段代码,其将块码限制为单一控制路径。由于该原因,基本块是控制流程中有用的基础单位。适宜地,翻译器19将主题代码17分割为多个基本块,其中每一个基本块是单一入口点处的第一指令和单一出口点处的最后指令之间的顺序的指令集(诸如转移、调用或分支指令)。翻译器19可仅选择这些基本块的一个(块模式),或选择一组基本块(组块(group block)模式)。一个组块适宜地包括被一起视为一个单位的两个或更多基本块。此外,翻译器可形成表示相同的但在不同进入条件下的主题代码的基本块的相等块(iso-block)。
在优选的实施例中,基于主题指令序列产生中间表示(IR)的树作为从原始主题程序17产生目标代码21的处理的一部分。IR树是由主题程序计算的表达式和由主题程序执行的运算的抽象表示。稍后,基于IR树产生(“植入”)目标代码21。IR节点的集合实际上是有向无环图(DAG),但被通俗地称为“树”。
本领域技术人员可认为,在一个实施例中,翻译器19是使用诸如C++的面向主题的编程语言实现的。例如,一个IR节点被实现为C++对象,并且对其它节点的引用被实现为对对应于那些其它节点的C++对象的C++引用。因此,IR树被实现为IR节点对象的集合,包括对彼此的各种引用。
此外,在所讨论的实施例中,IR产生使用了对应于主题架构的具体特征的一组寄存器定义,主题程序17规定为基于该主题架构运行。例如,存在对于主题架构上的每一个物理寄存器(即图1中的主题寄存器5)的唯一寄存器定义。因此,翻译器中的寄存器定义可被实现为包含对IR节点对象(即IR树)的引用的C++对象。被该组寄存器定义引用的所有IR树的集合被称为运行的IR森林(“森林”是因为其包含多个抽象寄存器根,每一个被称为IR树)。这些IR树和其它处理适宜地形成了翻译器19的一部分。
图1还示出了目标架构10的存储器18中的原生代码28。从主题代码的运行时翻译得到的目标代码21和为目标架构直接写入或编译的原生代码28之间存在区别。在一些实施例中,当其检测到控制的主题程序流程进入诸如对其存在主题代码的原生版本的主题库的一段主题代码17时,翻译器19实现原生结合。代替翻译主题代码,翻译器19使得等同的原生代码28在目标处理器13上执行。在示例性实施例中,如公开的PCT申请WO2005/008478中更详细地讨论的,翻译器19使用诸如原生代码或目标代码调用桩模块的定义的接口将产生的目标代码21与原生代码28结合,该PCT申请的内容在此通过引用而并入。
当在目标计算***10上运行时,图2更详细地示出了翻译器单元19。如上面所讨论的,翻译器19的前端包括对主题程序17的当前需要的一段解码,以提供多个主题代码块171a、171b、171c(通常每一个都包含主题代码的一个基本块),并且还与辅助翻译器19的稍后操作的每一个主题块和其中包含的主题指令相关地提供解码器信息172。在一些实施例中,翻译器19的核心192中的IR单元从解码主题指令产生中间表示(IR),并且恰好与中间表示相关地执行最优化。作为翻译器19的后端的一部分的编码器193产生(植入)可由目标处理器13执行的目标代码21。在该简单的例子中,产生三个目标代码块211a-211c,以便在目标***10上执行工作,其等同于在主题***1上执行主题代码块171a-171c。并且,编码器193可产生用于目标代码块211a-211c的一些或全部的控制代码212,其执行诸如设定目标块操作的环境和在合适的情况下将控制传递回翻译器19的功能。
在一些示例性实施例中,翻译器19还被设置为在主题代码17中识别***调用。如上所述,目标***10可使用不同的目标操作***20和不同的目标ISA,因此具有与主题ISA相比不同的一组***调用。此处,在翻译阶段,解码器191被设置为检测主题ISA的***调用,其中主题代码17调用主题操作***2。大多数现代操作***提供一个在普通用户层程序和操作***的剩余部分之间的库,通常为诸如glibc或MS LibC的C库(libc)。该C库处理将信息传递至操作***2的核心,并切换至更有特权的管理模式的低层详细内容,以及不需要在特权模式下完成的任何数据处理和准备。在POSIX和类似的***中,一些常用的示例性***调用为open,read,write,close,wait,execve,fork和kill。许多现代操作***具有数百个***调用。例如,Linux几乎具有300个不同的***调用,而FreeBSD具有约330个。此外,在一些情况下,需要保持对目标代码的控制并且不将执行控制直接从目标代码21传递至目标OS 20。在示例性实施例中,主题代码17中识别的至少一些***调用使得要产生的目标代码21包括调用回翻译器19的函数调用,其在此处称为“x_call”。这些x_call对于目标代码21就像已经对目标OS 20进行了***调用,但实际上将执行控制从目标代码21返回翻译器19。在示例性实施例中,翻译器19包括通过这样的x_call从目标代码21调用的目标OS接口单元(也称为“FUSE”)194。FUSE 194响应x_call,包括在适合的情况下执行对目标OS 20的实际***调用,并返回至目标代码21。因此,翻译器19有效地截取由目标代码21进行的***调用,并有机会检视和控制由目标代码21获得的***调用,同时目标代码21仍然好像已经对目标OS 20进行了***调用。
如图2所示,在一些示例性实施例中,翻译器19被设置为选择地截取在执行目标代码21期间产生的例外信号。翻译器19包括一个或多个和目标OS注册过的例外处理装置195,以便接收通过执行目标代码21而出现的至少一些类型的例外信号。因此,在合适的情况下,例外处理装置195能够选择性地介入对例外的处理,并通知翻译器19已经出现了某个例外。此处,例外处理装置195在适当的情况下(例如,返回目标代码21)处理例外并重新开始执行,或确定将例外信号传递至适合的原生例外处理装置,如在目标OS 20中。在一个实施例中,翻译器19提供一个代理信号处理装置(未示出),其接收选择的例外信号,并传递某些接收的例外信号,使其由合适的例外处理装置195处理。
图3是示出了根据本发明的示例性实施例的程序代码变换***的示意图。
首先,为了示例和容易解释,图3示出了具有多个处理器3a、3b的多处理器主题计算***1,该多个处理器执行主题代码的单独部分170a、170b(SC1&SC2)并访问存储在存储器子***(MS)8中的数据。
最常见地,在处理器3a、3b上执行的主题代码部分170a、170b通过引用地址空间(VAS)81访问物理存储器8,所述地址空间(VAS)81将主题代码170a、170b中引用的存储器访问地址映射成存储子***8中的物理存储器地址。因此,术语虚拟地址空间在本领域中用于区别代码的地址空间和物理寻址。
在一些环境下,第一和第二主题代码部分170a、170b都规定为访问物理存储器8的相同区域。在图3所示的示例情况下,诸如存储器8的页面的区通过主题代码部分170a、179b被映射到虚拟地址空间81。在其它情况下,明确共享的存储器被映射为两个不同的虚拟地址空间。
如上所述,主题计算架构1的存储器一致性模型限定了存储器访问的语义、和此处理器3a、3b和存储子***8可相对于主题代码17的原始程序顺序重新排列存储器访问的程度。在该例子中,主题架构1具有相对强的排序限制。也就是说,主题存储器一致性模型可限定连续存储和连续载入是按顺序的,但存储后是载入或载入后是存储可参照程序顺序重新排列。该示例性主题架构中的存储器一致性模型可被简要地概括成下述表格1。
表格1
第一指令 第二指令 限制
存储 存储 按顺序的
存储 载入 不按顺序的
载入 存储 不按顺序的
载入 载入 按顺序的
主题代码17依赖存储器一致性模型,以便正确地运行。实际上,主题代码通常被写入并被调试到使其在当前可用版本的主题硬件上运行的点。然而,在作为不同版本的主题计算***1的目标计算***10上实现主题代码17,或将主题代码17变换为在完全不同的目标计算***10上运行可揭示主题代码的弱点。此处,有许多使用各种不同形式的不严格的存储器一致性的多处理器***的实用的例子,包括Alpha,AMD64,IA64,PA-RISC,POWER,SPARC,x86和z系列(IBM360,370,390)等。
如图3所示,目标计算***10上的翻译器单元(TU)19将主题代码17变换为目标代码21,以便参考目标***的物理存储器8在多个目标处理器13a,13b上执行。在该例子中,目标计算***10的存储器一致性模型比主题***1的具有更弱、更不严格的限制。例如,目标存储器一致性模型可指定无论怎样都没有排序,并且目标存储器一致性模型允许载入和存储被任意重新排序,同时保持程序语义,如下面的表格2中概括的。
表格2
第一指 令第二指令 限制
存储 存储 不按顺序的
存储 载入 不按顺序的
载入 存储 不按顺序的
载入 载入 不按顺序的
如本领域技术人员熟知的,存储器子***18可包括被指定用于增加存储器访问速度的各种高速缓冲存储结构(未示出)。存储器子***18可包括两层或更多层物理存储器,其包括由片内或片外静态RAM提供的高速缓冲存储线、动态RAM中的主存储器、和大容量盘存储器等,它们根据主题计算***的架构由存储子***管理。有许多保护高速缓冲存储器一致性(也称为高速缓冲存储相关性)的机制来确保高速缓冲存储结构保持一致,但没有具体与所考虑的和此处还没进一步讨论的例子相关的。
现在将提供简化的例子来示例在目标计算***10中可能出现存储器一致性错误的一些方式。在该例子中,访问两个存储位置(*area1,*area2)。假设这些位置在不同的存储器页面上,以确保它们不在目标存储器子***18的高速缓冲存储结构内的相同的高速缓冲存储线上,和增加使对存储器18的访问次序颠倒的可能性。最初,我们限定存储在这些位置中的值为*area1=0和*area2=0。如下面的伪代码所示,第一处理器13a正在执行监控*area2中存储的值的目标代码21a的第一部分,并且根据*area1的值设定变量“a”:
while(*area2==0){}
int a=*area1
第二处理器13b执行目标代码21b的第二部分,该目标代码21b包含修改存储在两个存储位置中的值的指令:
*area1=1
*area2=1
直观地,我们期望变量“a”现在被设定为值“1”。的确,在严格排序的顺序一致的***中,这是真的。然而,可能出现存储器一致性错误使得变量“a”被设定为“0”。该错误的出现可能有两种原因。首先,不严格的存储排序可能允许第二存储(*area2=1)在第一存储(*area1=1)之前到达存储器。第一处理器13a能够读取*area1的旧值。第二,不严格的载入排序允许在第一处理器13a内的指令管道中顺序颠倒地发布载入,包括投机地执行的载入。在该情况下,在第一处理器13a等待*area2改变的同时,*area1中的值已经被投机地载入,并且一旦测试成功就不能被重新载入。其意味着即使正确地对来自第二处理器13b的存储进行排序,第一处理器13a仍可以不同的顺序读取更新值。
大多数多处理器***提供一种能够使程序代码优于硬件的不严格的存储器一致性模型,并设置更强的排序限制的安全网,从而提供抵抗存储器一致性错误的保护的方法。一个这样的安全网机制使用目标代码21a、21b中的串行化指令来形成合适的同步点,同时另一个这样的安全网通过在页面表格中设定属性来保护存储器的某些区。如现在要更详细地讨论的,可单独或组合使用这些和其它存储器一致性保护机制。
首先来看串行化指令的使用,一种普遍可用的形式是屏障指令(fence instruction)。屏障指令形成了将程序指令分割成屏障之前的指令、和随后的那些指令的内存屏障(memory barrier)。由屏障之前的指令引起的存储器访问在由屏障之后的指令引起的存储器访问之前执行。因此,屏障在获得存储器一致性上是有用的,但导致显著的性能损失。IBM POWER指令集架构中的指令SYNC是屏障指令的主要例子。屏障指令的其它具体变形也在POWER ISA中可用,诸如轻量级同步(LWSYNC)指令或强迫输入输出执行顺序(EIEIO)指令。其它例子包括来自Alpha ISA的MB和MBW、来自x86ISA的MFENCE和来自SPARC ISA的MEMBAR。
一些ISA也提供一种或更多在具体处理器内同步指令的执行的串行化指令。也就是说,指令同步使得处理器在同步之前完成所有指令的执行,并且放弃可能已经开始执行的同步之后的任何指令的结果。在执行了指令同步之后,程序中的随后的指令可接着开始执行。此处,IBM POWER指令集架构中的指令ISYNC是执行这样的指令同步的指令的主要例子。
这些串行化指令被***目标代码以确定与目标机器的默认存储器一致性模型不同的一个存储器一致性模型。将这些串行化指令***上面讨论的示例伪码产生了如下的修改的目标代码21a和21b。
对于第一处理器13a,串行化指令ISYNC被***(因为表格1中指定的载入-载入排序),使得目标代码21a变为:
while(*area2==0){}
isync
int a=*area1
对于第二处理器13b,串行化指令SYNC被***,使得目标代码21b变为:
*area1=1
sync
*area2=1
现在转向提供抵抗存储器一致性错误的另一个机制,一些目标计算***允许页表属性的操纵。作为具体例子,IBM POWER架构允许存储器18的某些区被指定作为禁止高速缓存和被防护的(下文中称为按顺序存储)。如果单独的存储指令访问存储器的这样的保护区,则以程序指定的顺序执行存储。方便地,存储器的一些页面被标记为按顺序存储,同时存储器的其它页面不是按顺序存储的。按顺序存储的页面可用于确认与目标机器的默认存储器一致性模型不同的一个存储器一致性模型。然而,与对非按顺序存储的页面的访问相比,对这样的按顺序存储的页面的访问通常导致了性能损失。
现在将更详细地描述本发明的示例性实施例,以便陈述上面概括的存储器一致性问题,同时一起最小化或避免与诸如串行化指令和按顺序存储的页面的存储器一致性保护机制相关联的严重性能损失。
图4是示意性流程图,其提供了本发明的示例性实施例中应用的方法的总体概览,该方法保护诸如参照图3在上面描述的目标计算***10的多处理器计算架构中的存储器一致性。
步骤401包括在第一存储器一致性模型下执行至少第一目标代码部分21a。也就是说,在步骤401中,至少第一目标代码部分21a是在可应用于目标计算***的架构的第一默认存储器一致性模型下在目标计算***中执行的。
步骤402包括检测用于访问可由第一目标代码部分21a和至少一个其它第二程序代码部分21b访问的共享存储器区域的请求。也就是说,在步骤402中,翻译器单元19被设置为关于存储器18中的共享存储器区域检测访问请求,所述共享存储器对于第一和第二目标代码部分21a、21b是可访问的(或将成为可访问的)。可使用各种机制来访问这样的共享存储器区域,并且如将在下面更详细地讨论的,考虑各种检测机制。
步骤403包括应用存储器一致性保护机制,使得当访问所检测的共享存储器区域时,第一目标代码部分21a中的至少某些指令或某些指令组在所保护的第二存储器一致性模型下执行。此处,翻译器单元19选择性地应用一种存储器一致性保护机制,该机制使得在第一目标代码部分21a内的所选择的指令以强制使用与第一模型不同的第二存储器一致性模型的方式访问识别的共享存储器区域。具体地讲,保护的第二存储器一致性模型提供了比第一模型更强的排序限制,其目的是防止此处提到的类型的存储器一致性错误。稍后,当第二代码部分21b也试图访问共享存储器区域时,进一步选择性地应用存储器一致性保护机制,使得第二程序代码部分21b中的至少选择的指令现在也关于所检测的共享存储器区域在被保护的第二存储器一致性模型下执行。
在该示例性实施例中,第一和第二目标代码部分21a、21b最初没有根据第二存储器一致性模型被限制,而是在默认的第一模型下执行。也就是说,目标代码最初是根据目标***的较高速度的默认的存储器一致性模型被创建和执行的。通过仅对那些访问已经被检测为共享存储器区域的存储器18的那些区的识别的目标代码指令应用存储器一致性保护机制,与更全面地对目标代码21访问的所有存储器应用增强的第二存储器一致性模型相比,由第二存储器一致性模型的约束和限制导致的性能损失被充分地减小。
图5是示出了目标计算***10的选择部分,以便进一步示出本发明的示例性实施例的示意图。在图5中,主题代码17是当被翻译成目标代码21时作为多个目标代码部分(例如多个线程)执行的多线程应用程序。示出了三个这样的代码部分21a-21c(T1,T2,T3)用于示例。
主题代码17适宜地为被变换为目标代码21,以便在目标***10上利用翻译器19的支持执行的应用程序。作为常见的例子,主题代码17是诸如网络服务器、数字内容服务器(例如,流媒体音频服务器或流媒体视频服务器)、文字处理器、电子数据表编辑器、图形图像编辑工具或数据库应用的复杂程序。目标计算***10通常需要同时运行许多这样的应用,除了诸如那些与操作***20和翻译器19相关的其它任务以外。
在动态二进制翻译的上下文中,主题代码17可采取为具体主题架构1专门创建(例如,编译)的二进制可执行的形式。因此,没有机会人工干预或回顾主题代码17,而是需要自动地强主题代码17变换成目标代码21(即,目标二进制),以便在目标计算***10上执行。在至少一些实施例中,此处讨论的机制将允许这样的变换处理自动地实现,同时也保护存储器一致性。
许多商业可获得应用程序作为多个处理和/或多个处理线程执行。此处,尽管具体实现基于具体计算架构而不同,每一个处理通常都具有相对大量的状态信息(也通常称为上下文信息),并且具有其自己的虚拟地址空间。通过对比,母处理可以产生通常共享其母处理的主题信息的一个或多个线程,并且来自相同处理的两个线程通常共享母处理的虚拟地址空间。在来自相同母处理的线程之间切换典型地比在处理之间切换的上下文更快,并且多线程是现代多处理器***上的一个大众化的编程和执行模型。尽管术语“处理”和“线程”被本领域技术人员广泛使用和理解,为了清楚起见,此处的描述通常是指程序代码的“一部分”。
如图5所示,除了已经描述的单元,示例性实施例的翻译器19还包括地址空间分配单元(ASAU)196、共享存储检测单元(SMDU)197、以及存储保护单元(MPU)198。
ASAU 196被设置为将多个虚拟地址空间区域(VASR)181分配给多个目标代码部分21a、21b、21c。第二,ASAU 196被设置为引导产生的目标代码部分21a-21c,以便访问多个分配的VASR 181中不同的几个。
SMDU 197被设置为检测由目标代码部分21a、21b、21c中的一个访问共享存储器区域的请求,其具体实施例将在下面讨论,并且识别需要存储器一致性保护的该目标代码部分内的一个或多个目标代码指令。
MPU 198被设置为对由SMDU 197识别的选择的目标代码指令应用存储器一致性保护。该存储器一致性保护使目标代码强制使用不同的存储器一致性模型,在该情况下具有更强的排序限制,从而保持由主题代码17要求的存储器一致性模型。适宜地,如稍后详细讨论的,MPU 198选择性地对目标代码应用串行化指令,和/或选择性地确认按顺序存储的页面。
在图5的例子中,三个目标代码部分T1、T2、T3(21a-21c)被示为每一个都与各个虚拟地址空间区域181a-181c相关联。此外,在该第一实施例中,ASAU 196分配与共享存储器区域相关联地使用的其它VASR 181d。
在ASAU 196的一个示例性实施例中,目标计算***10提供了多个不同的寻址模式。大多数普遍可用的计算***提供32位虚拟寻址,使得程序代码的具体部分的虚拟地址空间能够寻址物理存储器18的232个单独的元素(即字节、词)。因此,许多商业可用的应用程序期望在32位虚拟地址空间中运行。然而,一些计算***也允许更大的寻址模式,诸如64位模式,其可以代替或与较小的32位寻址模式平行地使用。方便地,翻译器单元19被设定为以64位寻址模式运行,从而具有64位虚拟地址空间(在下面称为,翻译器虚拟地址空间或翻译器VAS 180)。然后,地址空间分配单元196在较大的64位翻译器VAS 180内分配多个单独的32位虚拟地址空间区域(VASR)181。其它寻址选择也是可用的,并且可以按照合适的组合应用来实现相同的效果,诸如被子分割以便提供多个24位虚拟地址空间区域的32位翻译器VAS。
ASAU 196还被设置为将目标代码21的每一个部分都引导至选择的一个或多个VASR 181。如关于图2提到的,目标代码21a的每一个部分都被子分割成多个块211,其包括单独指令的短序列作为由翻译器19处理的最小单位。这些指令中的一些使存储器访问这样的载入或存储,并且具体目标代码部分21a内的大部分指令访问关于被分配至该部分的VASR 181a的私有存储器。然而,某些指令或指令组关于共享存储器进行存储器访问,并且被引导为访问用于共享存储器区域的VASR 181d。
在一个实施例中,当执行存储器操作时,目标代码21被产生为引用基址寄存器BR 15a。基址寄存器15a是大多数架构的快速和容易地可用的存储位置,并且可以在“基址加偏移”类型的存储器访问中有效地使用,但如果合适也可使用其它适合的存储器。基址寄存器BR被方便地提供作为该部分目标代码的上下文信息(即,该线程或处理)。基址寄存器BR 15a用于将给出了64位翻译器VAS 180中的开始地址的基址地址,作为由目标代码21的产生部分使用的32位VASR 181中的一个的开始地址存储。然后,由翻译器19产生目标代码部分21a、21b、21c的每一个,以便参照基址寄存器BR 15a中的开始地址进行存储器访问。
在图5的示例性例子中,对于目标代码部分21a,基址寄存器BR包含64位值“1<<32,232”,从而线程T1参照其分配的第一(32位)VASR 181a作为从该64位基址值的偏移进行存储器访问。简单地,对于第二目标代码部分21b,基址寄存器BR包含值“2<<32,232”作为第二32位VASR 181b的64位开始地址。
此处,示例主题代码17已经被创建为在32位VAS中运行,因此仅与32位地址相关。因此,翻译器19参照32位VASR 181产生相关部分的目标代码21a-21b。然而,由于这些32位VASR 181是从目标64位翻译器VAS 180分配的,当进行存储器访问时,目标代码使用全64位地址。这是通过将参照32位VASR 181的低32位地址与基址寄存器BR 15a中指定的全64位基址地址连接而方便地实现的。例如,目标寄存器r31用作基址寄存器以保持64位基址,并且目标寄存器r6在目标代码中用于保持所需32位地址。该地址如下面的伪码所示被组合:
r6=0×00003210 ;目标代码VASR中的32位地址
r31=0×0000000100000000 ;该VASR的64位地址
add r3,r31,r6 ;将地址与r3组合
Iwz r5,0(r3) ;使用r3中的组合地址访问存储器
此外,ASAU 196被设置为引导目标代码部分21a内的某些指令,使其引用所分配的VASR 181的不同的一个。具体地讲,涉及到共享存储器的访问的某些指令被引导至为共享存储器区域保留的VASR181d。
在一个示例性实现中,修改基址寄存器BR 15a中的开始地址,从而目标代码21中的随后的指令参照分配的VASR 181的不同的一个。也就是说,存储在基址寄存器BR 15a中的基址被修改,并且修改的基址被目标代码的具体块中的一个或更多的随后的指令使用,直到基址寄存器被重新设定为之前的值。此处,如在上面的例子中,BR15a中原始给出的值为作为分配给第一目标代码部分21a的VASR181a的64位开始地址的“1<<32,232”。在示例的例子中,暂时地将基址变为“0”将导致目标代码指令引用为共享存储器区域保留的第四VASR 181d。将BR 15a再次返回值“1<<32,232”导致目标代码21a引用分配的第一VASR 181a。
方便地,基址寄存器15a中的默认基址被设定为该部分目标代码21a的一部分上下文/状态。因此,可容易地从上下文获得默认值,并且当需要时,诸如在每一个目标代码块211开始处,可将默认值迅速地设定为默认值。
在另一个示例性实现中,也如图5所示,ASAU 196被配置为选择性地产生引用至少两个基址寄存器15a、15b的目标代码指令。方便地,第一基址寄存器BR1保持分配至目标代码21a-21c的当前部分的VASR 181a-181c的基址。同时,第二基址寄存器BR2保持分配给共享存储器区域的VASR 181d的基址。此处,目标代码指令被产生为执行与第一基址寄存器BR1或第二基址寄存器BR2或其组合相关的存储器访问。因此,产生始终仅引用第一基址寄存器BR1的目标代码21a的第一部分,使得该部分目标代码相对于相应的分配的VASR181a单独地操作。然而,当目标代码指令引用寄存器BR2中的基址时,目标代码被引导为访问共享存储器区域的VASR 181d。通过选择性地对第一和第二基址寄存器BR1、BR2植入引用,ASAU 196被设置为控制目标代码访问哪个VASR。
SMDU 197被配置为检测由目标代码部分21a、21b和21c中的一个访问共享存储器区域的请求。首先,该请求可采用开始与其它线程或处理共享的明确共享存储器区域的形式。第二,请求可采用与共享存储器相关的隐含请求的形式,诸如访问已经被映射到另一个线程的虚拟地址空间的存储器区域的请求。首先参照图6讨论明确的共享存储器的检测。然后,更详细地参照图7讨论隐含共享存储器的检测。
如上所述,翻译器19被配置为监控并截取由执行目标代码21进行的***呼叫。具体地讲,x_call被设置为将执行控制传递至翻译器19中的FUSE 194,从而对诸如mmap()的存储器映射***调用的行为进行仿真。
如果x_call不涉及共享存储器,则适宜地对目标OS进行***调用,以便按要求采取行动,诸如将私有非共享页面载入分配至目标代码的执行部分的VASR 181。然后,执行控制经由FUSE 194返回目标代码,并且目标代码接收上下文,如同从目标***调用返回的一样。
然而,当x_call涉及共享存储器时,由共享存储器检测单元197采取行动。此处,x_call或至少从x_call推导的信息被传递至SMDU197。作为具体例子,目标操作***20支持诸如shmget或mmap()的存储器映射***调用。作为UNIX和LINUX类型的操作***中的具体例子,mmap()***调用典型地采取形式mmap(start,length,prot,flags,fd,offset)来请求将从文件或由文件描述器fd指定的其它对象偏移offset处开始的字节length映射到在地址start处的虚拟存储器中。对于匿名文件,参数fd为空。参数prot描述设定读取和写入保护的所需存储器保护。参数flags包括与映射该对象的所有其它处理明确地共享该映射的标志MAP_SHARED等。可供替换地,参数flags包含创建私有写入时复制映射的标志MAP_PRIVATE。因此,mmap()***调用作为等同的x_call(例如,x_mmap())被植入目标代码,并能够明确地请求私有存储器区域或明确地请求共享存储器区域,从而由SMDU 197采取行动,在明确地请求私有存储器区域的情况下,对应的mmap()***调用被如上所述传递至目标OS 20。
图6是图5所示的目标计算***的更详细的示意图,以便示出由SMDU 197与映射明确的共享存储器的请求相关地采取行动。具体地讲,图6是翻译器VAS 180的一部分的示意性表示。
在图6所示的例子中,目标代码21a的当前执行部分是线程T1,其包含x_mmap()类***函数调用,以便请求明确共享的存储器区域182a。然而,所请求的共享存储器区域182a没有被映射到与该具体线程T1 21a相关联的虚拟地址空间区域181a。而是具有和所请求的共享存储器区域182a大小和偏移都相同的存储器区域182d被映射到为共享存储器保留的虚拟地址空间区域181d。所请求的共享存储器区域的指针PTR通过FUSE 194返回到T1目标代码21a,作为在mmap()***调用之后的期望的行为。在该示例性实施例中,32位指针作为32位VASR 181a中的开始地址被返回。然后,继续目标线程T1 21a的执行,就好像指针已经被提供至新映射的共享存储器区域。
可选择地,SMDU 197记录从x_mmap()调用的参数推导的所请求的存储器区域182a的详细内容。也就是说,SMDU形成每一个所请求的共享存储器区域182的映射,其方便地包括每一个共享存储器区域的大小和位置,并且也可识别目标代码的具体部分作为该区的所有者或始发者。并且FUSE 194和/或SMDU 197更新翻译器19中保持的主题状态,以便反应该新分配的共享存储器区域对于主题代码17出现的方式。
因为所请求的共享存储器区域182a还没有实际在第一目标代码线程T1 21a的VASR 181a内被映射,当线程T1试图访问未映射的存储器区域182a内的页面时,出现例外(例如,页面失败)。该例外由图2所示的例外处理器195截取,并被传递至SMDU 197,其能够识别正在试图访问该明确共享存储器区域182a的目标代码块。
响应该例外信号,识别目标代码指令被首先引导至为共享存储器保留的VASR 181d,然后应用存储器一致性保护机制。
如上所述,ASAU 196通过改变代码来修改基址寄存器BR 15a中的值,或者通过修改代码使其指向第二基址寄存器BR2 15b,将目标代码块中的至少某些指令重新引导至共享VASR 181d中的共享存储器区域182d。VASR 181d中的共享存储器区域182d被映射到物理存储器,从而目标代码中的相关指令获得到共享存储器区域182的访问。
该示例性实施例容易地使得能够检测访问共享存储器区域182的尝试,因为明确共享存储器区域没有在与执行线程T1相关联的虚拟地址空间区域181内被映射。然而,通过提供另外的虚拟地址空间区域181d和向其重新引导所选择的目标代码指令,所需共享存储器区域182仍然可由部分目标代码21访问。
并且,如下面将要更详细地讨论的,MPU 198向所识别的目标代码指令应用存储器一致性保护机制。也就是说,仅对试图访问共享存储器区域的目标代码21的那些块选择性地应用存储器一致性保护机制,以便保持存储器一致性。因此,影响相对少的指令。特别地,该机制不需要对整个程序或甚至整个线程应用昂贵的存储保护机制。
再次参照图5,应注意共享存储器区域的VASR 181d不与目标代码T1、T2和T3的执行部分中的任何一个的虚拟地址空间区域重叠。因此,由第二或第三目标代码部分T2、T3访问明确共享的存储器区域182的任何尝试最初都会失败,因为明确共享的存储器区域没有在与该线程相关联的相应的VASR 181b或181c内被映射。再次,由例外处理装置195处理得到的例外信号,并将其传递至SMDU 197,SMDU 197使得相关指令访问为共享存储器保留的VASR 181d并对其应用存储器一致性保护机制。因此,通过例外处理装置195和SMDU197检测试图访问明确共享的存储器区域的任何目标代码指令,并采取适当的行动。
图7是图5所示的目标计算***的更详细的示意图,以便示出与隐含共享的存储器区域相关的由SMDU 197采取的行动。具体地讲,图7是在开始诸如新线程的目标代码的一个新部分期间的翻译器VAS180的一部分的示意性表示,以便示出当在目标代码的一个新部分的开始开始隐含的存储器区域时用于保护存储器一致性的机制。具体地讲,图7涉及诸如LINUX类型操作***中的clone()的***调用。此处,正常的***响应是要在相同的共享虚拟地址空间中创建与母处理同时运行的子线程,其中子线程包含来自母处理的上下文信息的子集。因此,由clone()***调用创建的新线程将默认地占据相同的虚拟地址空间,从而与母处理共享存储器。然而,下面描述不同于该正常响应的示例性实施例的响应。
如图7A所示,在该例子中,第一线程T1正在第一VASR 181a中执行,并且映射到至少一个存储器区域182a中,对于该处理私有。此处,映射区182a典型地包含全局数据、起始堆内存、和可选择的另外的堆内存。当第一线程T1执行clone()***调用(方便地植入为x_call)时,使用图5的ASAU 196将新线程分配给单独的VASR 181b。在该例子中,由新线程T2 21b引用的基址寄存器15a包含值“2<<32”,从而线程T2被引导至第二VASR 181b。因为现在两个线程T1和T2被分配了单独的VASR,如图7所示,之前由线程T1映射的存储器区域182a将不被映射到与线程T2相关联的虚拟地址空间区域181b中。因此,具有对应于VASR 181a中的私有映射区182a的大小和偏移的等同区182b在与线程T2相关联的第二VASR 181b中仍未映射。
如图7B所示,线程T1继续访问私有存储器区域182a,而在该处没有对线程T1的部分目标代码21a进行任何改变。这与参照图5和图6讨论的处理明确共享的存储器的机制不同。同时,线程T2 21a仍可访问潜在共享的存储器区域182a,如果T2 21b试图访问其自己的VASR 181b内的对应的区182b,则相关页面不被映射,并且会出现例外。
例外信号被传递至与例外处理装置195协作处理例外的SMDU197。首先,线程T1中断,因为T1拥有第二线程T2 21b试图访问的存储器区域182a的映射。此处,从线程T1对相关存储器区域182a的所有待定访问已完成。第二,如图7C所示,相同大小和偏移的对应的存储器区域182d现在在共享VASR 181d中被映射,使得由第一线程T1引用的物理存储器中的数据现在在区182a而不是在共享区182d可用。可将有故障的单一页面复制到共享存储器区域182d,或者现在可复制整个相关存储器区域。已复制的共享区182a现在没有在第一线程T1 21a的虚拟地址空间区域181中映射,从而线程T1可不再访问区182a,例如通过使用munmap()或通过使区被保护。
然后,T1通知T2,重试对共享区域181d中的新创建的存储器区域182d的访问是安全的。T1重新开始正常执行。T2重试有故障的存储器访问,这一次是通过访问共享的存储器区域域181d并且应用了适合的存储器一致性保护,然后重新开始执行。
如图7C所示,如果目标代码部分T1或T2随后再次访问共享区182(该共享区现在是不可访问的/在它们的私有VASR181a、181b中未映射),则将出现例外并且存储器访问将通过在由MPU198应用的适合的存储器一致性保护下,由例外处理装置195访问共享地址区域182d来完成。
作为该机制的结果,目标代码部分T1和T2中的适合的指令被引导至共享的虚拟地址空间区域181d,以获得到共享数据区182d的访问,并且仅对试图访问共享数据区182d的目标代码的那些部分应用第二存储器一致性模型的较强的限制。
现在,继续处理,并且T1和T2并行地执行。每一次线程中的一个,例如第二线程T2,试图访问已经由另一线程,例如第一线程映射的存储器区域,会出现例外,该例外被处理为从所有者线程T1将相关区或页面移至共享VASR 181d,并选择性地向目标代码的该区应用存储器一致性保护机制。试图访问现在共享的存储器区域的任何其它线程导致例外,并且该线程中的相关代码同样被引导并服从存储器一致性保护。因此,机制应用于任何数量的程序代码部分(线程T1、T2和T3等)。
一种可供替换的机制使用在许多Linux和UNIX类型的操作***中可用的重映射***调用。此处,MREMAP***调用允许改变目标***10所使用的页表,以控制对存储器18的访问。通过改变页表,存储器的页面被映射到虚拟地址空间180中的一个新位置,从而直接从第一VASR 181a直接移至第二VASR 181b。从执行用户-空间线程的观点来看,重映射是原子地进行的,从而第一线程T1不需要被中断或通知。
图7D是示出了多个地址空间区域181的翻译器VAS 180的另一个视图,但为了容易示例,此处VASR 181被示为在它们的相应的基址处对齐。并且,图7D示出了由记录每一个VASR 181内的映射区的SMDU 197保持的VASR映像199。在该示例性实施例中,VASR都为相等的32位大小,并且单个32位映像方便地记录每一个VASR内的映射存储器区域。因此,即使私有地映射的区域最初存留在一个目标代码部分的VASR中,通过咨询映像199容易地检测隐含共享存储器,以确定具体VASR中的所请求的32位地址已在另一个VASR的相应位置处映射。响应时,仅对访问检测的共享存储器区域目标代码指令执行图7B和7C所示的行动。
此处讨论的示例性实施例正是用于目标代码部分21a-21c的每一个的VASR 181。然而,其它实施例也是可能的,并且被构思为所描述的示例性实施例的变形。例如,可提供多于一个共享区。在一个可供替换的实施例中,每一个目标代码部分21a-21c与仅保持私有存储器区域的相应私有VASR和保持共享存储器区域以及一个或多个私有共享存储器区域的相应的共享存储器区域相关联。此处,多个目标代码部分的多个VASR的使用仍允许共享存储器,尤其是隐含共享的存储器,容易地被SMDU 197检测。
图8更详细地示出了存储器一致性保护机制的示例性实施例。
图8的例子示出了主题代码块171和相应的目标代码块211。在执行目标代码块211的一些点处,与共享存储器区域相关地出现了例外,并且如上所述,由例外处理装置195与ASAU 196、SMDU 197和MPU 198协作地采取行动来保护存储器一致性。在图8的例子中,在执行该块的途中与指令相关地出现例外,因此块211已被分为两个半部以供示例,其中上半部表示已执行的指令,而下半部中剩余的还没开始执行。此处,存储保护机制首先试图完成当前块211的执行,并采取运行中的措施来保护存储器一致性。之后,当已经实现适合的固定的状态时,对目标代码进行较长期的改变,例如重新产生整个块211,目的是避免在将来执行该目标代码块时出现例外。
首先看存储器一致性保护机制采取的紧急措施,将描述各种示例性实施例。
在一个示例性实施例(在图8中标为①)中,目标代码21被产生为在适合的同步点处包括空操作,例如在每一对存储之间。这些空操作,诸如IBM POWER ISA中的NOP指令,仅具有使处理器在具体数量的时钟周期内不进行任何操作的效果,因此可方便地用作位置标志符。现在用激活串行化指令(例如,SYNC和ISYNC)替换空指令,以便对目标代码应用存储器一致性安全网。并且,如上所述,代码被修改为引用共享VASR 181d。因此,该实施例至少部分修改了准备用于将来执行的块211的非执行部分。
在另一个实施例(在图8中标为②)中,目标代码块的执行是通过存留在MPU 198内或与其相关联的主题-目标编译器STInt 200来完成的。也就是说,执行是通过STInt 200逐个指令地将对应的主题代码块171b的剩余指令编译为等同的目标代码指令来完成的。此处,MPU 198使编译器应用串行化指令来形成适合的同步点(例如,在载入或存储后***SYNC和ISYNC)。然而,该实施例假设可用适合的主题状态,以便通过STInt 200开始执行。
而在另一个实施例中,立即重新产生至少目标块的未执行部分,以便***串行化指令。也就是说,用修改的版本代替目标代码块211的剩余部分,其中在确定的同步点***串行化指令。再一次,该实施例假设可用适合的主题状态,从而重新产生的目标代码可再次从已知状态向前移动。
当适合的主题状态在出现例外的点处不可用时,MPU 198适合地在目标代码中向回翻以达到可实现所需主题状态的检验点或恢复点。上面引用的WO2005/006106中详细讨论了达到与例外相关的主题状态的示例机制。此处,提供检验点块,诸如块的开始或结束或块内的选择点。MPU寻找最后达到的检验点,从而能够恢复检验点的主题状态。现在,块的执行是通过参照恢复主题状态从检验点前进而完成的。
在又一修改中,MPU 198向前翻至出现例外的点后的下一个检验点。此处,通过编译已经在块211中产生的目标代码的目标-目标编译器TTInt 201来辅助MPU,同时***适合的串行化指令来保护存储器一致性,直到目标代码向前翻至下一检验点。WO2006/103395中详细讨论了恢复主题状态的该向前翻机制。作为又一修改,目标-目标编译器TTInt 201聚集了向前翻操作过程中的翻译提示,诸如记录那些失败的存储器访问和没有失败的那些存储器访问,从而改进稍后的改目标代码块的重新产生。方便地,这些翻译提示通过最初产生具有NOP空操作的目标代码,然后选择性地用翻译提示标志替代NOP而被植入目标代码。
已处理了该目标代码块211的紧急需要,翻译器19现在可以进一步关注块211。例如,重新产生所有或部分整个目标块211,以便包括遍及该块的串行化指令(例如SYNC和ISYNC),或保护块内的选择的指令组。因此,当将来执行重新产生的目标代码块211b时,该块服从与共享存储器访问相关的存储器一致性保护。目标代码的再产生可使用通过执行从目标代码块的之前的化身而收集的翻译提示。可立即执行重新产生,或通过使用图8中示意性地示出的标志211f将块标记为需要重新产生,延迟执行直到一个稍后的点,诸如当下一个需要执行块211b时。重新产生处理可以是迭代的,并且采取几种途径。也就是说,在第一重新产生之后选择性地对第一组指令应用存储器一致性保护,然后对第二重新产生中的第二组指令选择性地应用存储器一致性保护。此处,从之前的一个或多个化身收集的翻译提示可用于辅助重新产生的最新迭代。此外,重新产生处理可包括目标代码的两个或更多基本块的组合,其来自具有一个唯一入口点和/或多于一个的唯一出口点和/或具有内部转移(jump)的组块。此处,目标代码中嵌入的翻译提示有助于允许翻译器形成已经考虑了相关基本块的之前的重新产生的有效组块,从而减少了组块的重新产生。
在实际应用中,可使用代码的具体段来访问共享和私有存储器。如上所述,目标代码被原始地产生为适合于相关私有VASR,181a-c中的私有存储器。如果代码被重新翻译为适合于共享存储器,则当试图访问私有存储器时将产生例外,因为私有存储器没有在共享VASR181d中映射。因此,一个选择是再次将代码翻译回适合于私有存储器的原始格式。被映射到共享VASR 181d或私有VASR 181a-c的存储器页面的相互独有的性质确保了永远检测该情况的变化。
在处理例外和重翻译一个或多个代码块中存在附加(overhead)。在一些程序中,相对不频繁地遇到重翻译附加,因此是最适合的全面方案。然而,已经发现了一些例子涉及频繁的重翻译,诸如当从程序内的许多不同站点调用一段代码时。一个具体的例子是存储复制函数memcpy()。此处,机制已被进一步开发并修改为解决该问题。
如图8所示,翻译器19可保留至少两个不同版本的目标块211。第一个版本211A是没有存储器一致性保护的原始翻译,其根据重排序和由目标***执行的其它最优化快速地执行。在该参照具有串行化指令的共享VASR 181d的例子中,第二个版本211B服从于存储器一致性保护,因此执行得较慢。当该块在执行程序期间下一个被遇到时,翻译器可选择性地执行第一或第二版本211A或211B。在进入函数时,应用动态测试来确定被访问的存储器的类型,即,私有的还是共享的,然后选择适合的版本。该方案在减少了翻译附加的同时,在执行动态测试中存在执行损失。
在另一个修改中,翻译器执行循环最优化。此处,第一次执行循环,并导致了存储例外,因为循环内的存储器访问指向共享存储器。现在,翻译器可重翻译循环中的代码以指向共享存储器,从而将来的指向共享存储器的执行失败的可能性较小。设置动态检验以明确循环中的代码是要访问私有还是共享存储器。并且,翻译器可试图将动态校验升到循环以外,并将其放置在循环之前,从而进一步减少执行工作负载。
作为动态地校验调用代码的替换,另一个选择是在调用方站点嵌入专用代码。另一个选择是将调用方专门化为具体函数。也就是说,将调用方专门化为调用私有类型或共享类型访问器函数,以分别访问私有或共享存储器。例如:
Caller>memcopy>memory
变为:
Caller1(private)>memcopy_private>private memory
Caller2(shared)>memcopy_shared>shared memory
这些专用调用方也可涉及其它的间接层(即作为调用栈上的多余条目的包装器函数)。此处,访问的存储地址是由调用方确定的,并且存储地址仅被访问器(例如memcopy)使用。包装器函数最初被设定为调用它们的后继的私有版本。因此,检查调用栈确定了需要被专用化的包装器函数,从而允许来自该调用方的未来的调用成功。适宜地,前进的专用化一次改编一个包装器层,从离访问器函数最近的开始,直到每一个层都被专用化为私有和共享版本。
图9是提供了存储器一致性保护方法的总体概览作为此处讨论的各种详细实施例的示意性流程图。
在步骤901中,在单独的虚拟地址空间区域中执行第一和第二代码部分。例如,第一和第二目标代码部分21a、21b分别关于不同和不重叠的第一和第二虚拟地址空间区域181a、181b执行。
步骤902可选择地包括记录每一个虚拟地址空间区域181a、181b内的映射区182a、182b。此处,响应于存储器映射行动在存储器映像199中记录每一个映射存储器区域的地址偏移和大小(地址范围),诸如mmap()***呼叫等。
在步骤903中,该方法包括检测对没有在与当前执行的代码部分相关联的地址空间中映射,而在多个地址空间的另一个中映射的存储器区域的访问请求。此处,对应的存储器区域在与另一个执行代码部分相关联的地址空间中、或在为共享存储器保留的单独的地址空间中映射。在任一情况下,当前执行的代码部分的访问请求都导致存储例外,并且响应于存储例外,确定当前执行的代码部分正在试图访问共享存储器区域。
在步骤904中,该方法包括修改当前执行的代码,以应用使代码在具有预定限制的存储器一致性模型下执行的存储器一致性保护机制。并且,当前执行的代码被修改为被引导至为共享存储器保留的地址空间中的预定共享存储器区域。
最后,在步骤905中,当共享存储器区域没有已经存留在为共享存储器保留的地址空间内时,共享存储器区域被移动至这样的地址空间并且未被映射,或者至少在与当前代码部分相关联的地址空间中被保护。
考虑到开始诸如上述的clone()***调用的新的执行代码部分的机制,应理解为步骤901还可包括检测这样的开始新执行的代码部分的尝试,为新执行的代码部分分配单独的地址空间,和在新分配的单独的地址空间中执行新的代码部分。
应理解为图9中示出的步骤不需要以示出的顺序执行。作为具体例子,应理解为可在每一个新的存储器区域被映射到具体地址空间中时可动态地执行在每一个地址空间中记录映射区的步骤902,所述每一个新的存储器区域被映射到具体地址空间中是在在单独的地址空间中执行多个代码部分的每一个的步骤901之前、平行或之后执行的。此外,可预先选择性地执行步骤904和905,从而目标代码先被产生为具有对其应用的存储器一致性保护机制。这些可供替换的实现可取决于翻译器19内的设定。当翻译器预计,作为变换主体代码17的结果,这样的可选择的实现对于具体的程序段是有益的,则存储器一致性保护机制被应用于产生的目标代码21。
还应理解为上述机制不限于在单个应用程序中操作的处理和线程,而也可应用于同时在目标计算***上操作的一组或一套程序。也就是说,两个或更多程序(任务)可以在上述机制下共享存储器的方式一起操作。
图10是根据本发明的另一个实施例在MPU 198中实现存储器一致性保护机制的方法的示意性流程图。上面详细讨论的存储器一致性保护机制对产生的目标代码应用串行化指令。在可供替换的配置中,在某些架构的目标计算***上使用页面标志修改,以在存储器18中创建按顺序存储的页面。
在步骤1001中,多个目标代码部分中的每一个都在单独的虚拟地址空间区域中执行,与上面讨论的实施例相似。在步骤1002中,该方法包括,例如通过使用图7D的VASR映像199记录被映射到多个地址空间的每一个中的存储器区域。这些步骤以上述方式被图5的ASAU 196适宜地执行。
在步骤1003中,该方法包括检测开始共享存储器区域的请求。在一个具体实施例中,该请求是诸如明确地请求共享存储器的mmap()的存储器映射***调用。在另一个例子中,当子线程试图访问没有在其自己的地址空间中映射,而在母线程的地址空间内映射的区域时,出现例外,其中子线程已经诸如通过clone()***调用产生。适宜地,如上所述地使用SMDU 197的检测机制。
在步骤1004中,通过操纵页表属性来标记所检测的共享存储器区域的一个或多个页面,使得强制对这些页面的访问跟随第二、非默认存储器一致性模型。作为具体例子,使用基于PowerPC架构的***硬件的实现来允许将相关页面标记为所需有序一致性。
该实施例有利地没有要求共享存储器区域182移动至单独的地址空间区域181。而是共享存储器区域182被映射到需要访问共享存储器区域182的每一个目标代码部分21a、21b、21c的VASR 181a、181b、181c。访问共享区的任何代码将以按顺序存储的方式这样做,由此应用所需存储器一致性模型。此外,目标代码将没有页面故障地访问共享存储器区域182,避免了目标代码的修改。
图11是包括翻译器VAS 180的目标计算***的部分的示意图,以进一步示出与按顺序存储的页面相关的该示例性实施例,以及将虚拟地址空间180映射到物理存储子***18的页表PT 183。
在图11A中,第一代码部分T1 21a引起明确地请求共享存储器的mmap()类型***调用,例如文件后备的mmap_shared存储器。翻译器单元19中的FUSE 194截取***调用,并且如果页面还没有被标记为按顺序存储,则使区域的高速缓存线无效,并在页表PT 183中将页面标记为按顺序存储。该文件接着被映射到第一代码部分T121a的VASR 181a中作为共享存储器区域182a。
如图11B所示,当第二目标代码部分21b试图访问共享存储器区域182a时,将出现例外,因为共享存储器区域当前没有在相关VASR181b中映射。作为响应,SMDU 197也将共享存储器区域182b映射到第二VASR 181b中,并且在还没有这样标记之处,通过操纵页表属性将相关存储器页面标记为按顺序存储。
图11B还示出了如果出现clone()***调用时***的响应。代码部分21b中的新线程被分配了一个单独的和不同的VASR 181b,其不与母处理21a的VASR 181a重叠。在该情况下,第一代码部分21a的第一VASR 181a中的之前私有的存储器区域域182a现在可变为共享。即使存储器182a的某些区域已经在VASR 181a母处理中被映射,其对于新克隆的线程仍是为映射的。如果第二代码部分21b现在试图访问在其自己的VASR 181b中未映射而在母处理21a的VASR 181a中的对应区182a处被映射的存储器区域域182b,则子线程T221b将导致例外。SMDU 197将所需文件映射到子线程的VASR,以将共享存储器区域182b映射到这些VASR 181a、181b两者的相同的相对位置,以便向目标代码21a、21b的两个部分提供到物理存储器的相同页面的访问。在该情况下,之前私有,但现在隐含共享的存储器区域182在页表PT 183中被标记为按顺序存储。
主要关于用于加速、仿真或翻译程序代码的程序代码变换***在上面讨论了示例性实施例。此外,此处讨论的机制可应用于调试工具,其检测并选择性地自动校正对于存储器一致性错误易损的程序代码。设计问题或程序缺陷在共享存储器多处理器架构中难以发现、隔离和校正。未检测的程序缺陷造成了经常导致***故障、延迟新软件发布、或甚至需要发布后的软件更新的不适宜的操作。为了该目的,此处的控制/翻译器单元被配置为作为调试工具运行,以检测共享存储器区域并向主题代码应用适合的代码修改,诸如***串行化指令或修改页表属性,从而调试产生的目标代码。
尽管已示出并描述了几个示例性实施例,本领域技术人员应理解为在不偏离由所附权利要求限定的本发明的范围的情况下可进行各种修改和变形。
请注意,所有与该说明书同时或在其之前申请的与该申请有关的论文和文献、与该说明书一起对于公众公开的论文和文献、以及所有这样的论文和文献的内容在此通过引用而并入。
该说明书(包括任何所附权利要求、摘要和附图)中公开的所有特征、和/或如此公开的任何方法或处理的所有步骤可组合成任何组合,除了至少一些这样的特征和/或步骤相互排斥的组合。
该说明书(包括任何所附权利要求、摘要和附图)中公开的每一个特征都可被用于相同、等同或相似目的的可供替换的特征代替,除非特别说明。因此,除非特别说明以外,每一个公开的特征都是一个仅具有一类系列等同或相似的特征的例子。
本发明不限于上述实施例的详细内容。本发明延伸到该说明书(包括任何所附权利要求、摘要和附图)中公开的特征的任何新颖的一个,或任何新颖的组合,或如此公开的任何方法的步骤的任何新颖的一个,或任何新颖的组合。