一种残膜回收机防缠绕挑膜装置的制 一种秧草收获机用电力驱动行走机构

修复弱内存序问题的方法及装置与流程

2022-05-21 05:11:38 来源:中国专利 TAG:


1.本技术涉及计算机技术领域,尤其涉及一种修复弱内存序问题的方法及装置。


背景技术:

2.当基于非弱内存模型开发的多线程程序,在采用弱内存模型(weak memory model)的计算机设备中运行时,由于不同内存模型下硬件所支持的指令语义不同,因此可能会导致该程序中并行运行的线程在执行用于访存的读写指令时乱序,从而出现弱内存序的问题。
3.例如,基于强内存模型(strong memory model)开发的多线程程序,在采用弱内存模型的计算机设备中运行时,该程序中并行运行的线程执行用于访存的读写指令时,即可能出现弱内存序的问题。这样的话,该程序所要实现的功能可能会出现逻辑上的错误,从而导致该程序运行后输出的结果不准确。
4.基于此,如何修复多线程程序弱内存序的问题,是亟待解决的技术问题。


技术实现要素:

5.本技术提供了一种修复弱内存序问题的方法及装置,该方法能够在多线程程序的编译阶段,自动修复该程序中的弱内存序问题。
6.为达上述目的,本技术提供如下技术方案:
7.第一方面,本技术提供一种修复弱内存序问题的方法,该方法包括:在待修复代码中确定读写指令集。对该读写指令集中的指令进行分类,以确定目标指令。在目标指令的前一条读写指令和目标指令之间插入内存屏障指令。其中,该读写指令集包括待修复代码中的读指令和/或写指令,该读写指令集中的指令用于访问内存。
8.通过本技术的提供方法,可以通过对待修复指令进行分类,以确定出目标指令。然后,在目标指令前插入内存屏障指令,以使目标指令能够按照程序本身要求的顺序去执行,从而实现了自动的修复多线程程序的弱内存序的问题。通过本技术实施例提供的方法可以自动的修复多线程程序的弱内存序问题,大大提高了程序弱内存序问题修复的效率。
9.在一种可能的设计方式中,上述“对读写指令集中的指令进行分类,以确定目标指令”具体包括:在该读写指令集中确定第一类指令;根据该第一类指令,确定目标指令。其中,该第一类指令中的指令是弱内存序安全的指令。目标指令是上述读写指令集中、除该第一类指令之外的指令。
10.在另一种可能的设计方式中,上述“根据第一类指令,确定目标指令”具体包括:基于第一类指令,确定目标指令集;基于优化策略,在该目标指令集中确定目标指令。其中,该目标指令集包括上述读写指令集中,除该第一类指令之外的全部指令。该优化策略用于指示需要修复弱内存序问题的读写指令类型。
11.在另一种可能的设计方式中,上述优化策略包括以下策略中的至少一种:第一策略、将目标指令集中属于白名单中的读写指令,确定为目标指令;或者,将目标指令集中,除
黑名单中的读写指令之外的读写指令,确定为目标指令。第二策略、将目标指令集中具有上下文依赖关系的读写指令中,仅作为依赖的读写指令,确定为目标指令。第三策略、将目标指令集中除与专用寄存器有关的读写指令之外的读写指令,确定为目标指令。第四策略、将目标指令集中除与输入输出参数有关的读写指令之外的读写指令,确定为目标指令。
12.在另一种可能的设计方式中,上述的第一类指令包括:读写线程间非共享变量的指令、或具有保序语义的读写指令中的至少一种。
13.通过该几种可能的设计,可以准确识别出安全的、不存在弱内存序问题的第一类指令,并通过排除第一类指令,从而确定目标指令。通过该方法,可以快速的排除掉待修复代码中无需修复的读写指令,从而可以最大限度的减少不必要的内存屏障指令的插入,从而提高了修复后的多线程程序的运行性能。
14.另外,通过优化策略,可以进一步的减少不必要的内存屏障指令的插入,从而进一步的提高了修复后的多线程程序的运行性能。
15.在另一种可能的设计方式中,上述“对该读写指令集中的指令进行分类,以确定目标指令”,具体包括:基于上述的优化策略,对该读写指令集中的指令进行分类,以确定目标指令。其中,该优化策略用于指示需要修复弱内存序问题的读写指令类型。
16.通过该可能的实现方式,本技术可以通过优化策略,在读写指令集中确定出需要插入内存屏障指令的读写指令,这样,即可减少不必要的内存屏障指令的插入,从而提高了修复后的多线程程序的运行性能。
17.在另一种可能的设计方式中,上述方法还包括:获取用户配置的第五策略。将该第五策略添加至上述优化策略中。
18.这里,第五策略可以是用户自定义配置的策略。这样的话,通过该可能的设计,本技术允许通过用户自定义配置的策略对待修复代码进行修复,从而提高了本技术应用的灵活性。
19.在另一种可能的设计方式中,在上述“确定所述目标指令”之前,上述方法还包括:接收指示信息,该指示信息用于指示用户从待选优化策略中选择所述优化策略。
20.这里,该待选优化策略可以是修复装置预置的优化策略。这样,通过该可能的设计方式,用户可以待选优化策略中自由选择用于修复待修复代码的优化策略,从而提高了本技术应用的灵活性。
21.通过该可能的实现方式,可以使用户自定义配置优化策略,从而实现了本技术方法的灵活应用。
22.在另一种可能的设计方式中,上述“确定读写指令集”具体包括:对目标函数中的指令进行识别,以确定该读写指令集。其中,目标函数是上述待修复代码中的任意一个函数。
23.通过该可能的设计,本技术可以以函数为单位来识别并修复待修复代码中的弱内存序问题,从而本技术的方法可以应用于大规模的多线程程序的弱内存序问题的修复,进而提高了本技术方法的实用性。
24.在另一种可能的设计方式中,上述待修复代码是多线程程序的源代码经编译器编译得到的中间语言。
25.在另一种可能的设计方式中,上述待修复代码是多线程程序的源代码经编译器编
译得到的汇编代码。
26.通过该两种可能的设计,本技术提供的修复弱内存序问题的方法,可以和多线程程序的源代码编译同步执行,从而实现了自动的对该多线程程序的弱内存序问题的修复,进而提高了修复该多线程程序的弱内存序问题的效率。
27.第二方面,本技术提供了一种修复弱内存序问题的装置。
28.在一种可能的设计方式中,该装置用于执行上述第一方面提供的任一种方法。本技术可以根据上述第一方面提供的任一种方法,对该装置进行功能模块的划分。例如,可以对应各个功能划分各个功能模块,也可以将两个或两个以上的功能集成在一个处理模块中。示例性的,本技术可以按照功能将该装置划分为确定单元和插入单元等。上述划分的各个功能模块执行的可能的技术方案和有益效果的描述均可以参考上述第一方面或其相应的可能的设计提供的技术方案,此处不再赘述。
29.在另一种可能的设计中,该修复弱内存序问题的装置包括:存储器和一个或多个处理器,存储器和处理器耦合。存储器用于存储计算机指令,处理器用于调用该计算机指令,以执行如第一方面及其任一种可能的设计方式提供的任一种方法。
30.第三方面,本技术提供了一种计算机可读存储介质,如计算机非瞬态的可读存储介质。其上储存有计算机程序(或指令),当该计算机程序(或指令)在修复弱内存序问题的装置上运行时,使得该修复弱内存序问题的装置执行上述第一方面中或第二方面中的任一种可能的实现方式提供的任一种方法。
31.第四方面,本技术提供了一种计算机程序产品,当其在修复弱内存序问题的装置上运行时,使得第一方面中的任一种可能的实现方式提供的任一种方法被执行。
32.第五方面,本技术提供了一种芯片系统,包括:处理器,处理器用于从存储器中调用并运行该存储器中存储的计算机程序,执行第一方面中的实现方式提供的任一种方法。
33.可以理解的是,上述提供的任一种装置、计算机存储介质、计算机程序产品或芯片系统等均可以应用于上文所提供的对应的方法,因此,其所能达到的有益效果可参考对应的方法中的有益效果,此处不再赘述。
34.在本技术中,上述修复弱内存序问题的装置的名字对设备或功能模块本身不构成限定,在实际实现中,这些设备或功能模块可以以其他名称出现。只要各个设备或功能模块的功能和本技术类似,属于本技术权利要求及其等同技术的范围之内。
35.本技术的这些方面或其他方面在以下的描述中会更加简明易懂。
附图说明
36.图1为现有技术中将程序源代码编译为机器可执行程序代码的过程示意图;
37.图2为本技术实施例提供的一种计算设备的硬件结构示意图;
38.图3为本技术实施例提供的一种修复弱内存序问题的方法的流程示意图;
39.图4a为本技术实施例提供的一种修复装置基于图形交互界面获取用户从待选优化策略中选择的优化策略的示意图;
40.图4b为为本技术实施例提供的另一种修复弱内存序问题的方法的流程示意图;
41.图5为本技术实施例提供的一种修复装置的结构示意图;
42.图6为本技术实施例提供的一种芯片系统的结构示意图;
43.图7为本技术实施例提供的计算机程序产品的结构示意图。
具体实施方式
44.为了更清楚的理解本技术实施例,下面对本技术实施例中涉及的部分术语或技术进行说明:
45.1)、编译器
46.编译器通常用于将“一种语言”翻译为“另一种语言”。例如,将开发人员依据需求,采用高级计算机语言(例如c语言,c 语言等)开发出的程序源代码,翻译为机器可以识别并运行的机器语言代码(例如二进制代码)。
47.一般的,编译器可以集成汇编功能。这样,编译器即可先将经预处理器(preprocessor)处理的程序源代码,编译为汇编代码。该汇编代码即为汇编语言代码。接着,再进一步的通过汇编功能将该汇编代码编译为目标代码。该目标代码即为机器可以识别的语言代码,例如是二进制代码。这样的话,该目标代码经链接器(linker)将该目标代码中各个独立汇编的机器语言程序组合起来,即能得到机器可执行的程序代码。
48.可选的,为了提高编译效果,编译器将经预处理器处理的程序源代码,编译为汇编代码之前,先编译得到中间语言。该中间语言是编译器对预处理后的程序源代码进行解析后生成的,该中间语言用于优化编译器编译得到目标代码。
49.作为示例,参考图1,图1示出了将程序源代码编译为机器可执行程序代码的过程示意图。
50.如图1所示,程序源代码经预处理器11处理后,输入编译器12。编译器12的子编译器121可以将预处理后的程序源代码编译为汇编代码并输出。接着,汇编器122将子编译器121输出的汇编代码进行汇编编译,以得到目标代码。该目标代码即为机器可以识别的代码。最后,目标代码经链接器13处理后,即可得到机器可以运行的可执行程序。
51.其中,在子编译器121将经预处理的程序源代码解析后,可以生成中间语言。子编译器121还可以将该中间语言进行进一步编译,即可得到图1所示的汇编代码。
52.2)、多线程程序
53.正在运行的程序的实例,通常称为进程。一个进程可以包括至少一个线程,线程是指进程中的一个单一顺序的控制流。通常,一个进程中可以并发多个线程,该多个线程可以通过计算机设备中的多个处理核并行运行,以执行不同的任务。当然,一个进程中也可以仅有一个线程,对此不做限定。
54.因此,多线程程序是指,在运行过程中,该程序的一个进程中包括有多个线程的程序。
55.3)、其他术语
56.在本技术实施例中,“示例性的”或者“例如”等词用于表示作例子、例证或说明。本技术实施例中被描述为“示例性的”或者“例如”的任何实施例或设计方案不应被解释为比其它实施例或设计方案更优选或更具优势。确切而言,使用“示例性的”或者“例如”等词旨在以具体方式呈现相关概念。
57.在本技术的实施例中,术语“第一”、“第二”仅用于描述目的,而不能理解为指示或暗示相对重要性或者隐含指明所指示的技术特征的数量。由此,限定有“第一”、“第二”的特
征可以明示或者隐含地包括一个或者更多个该特征。在本技术的描述中,除非另有说明,“多个”的含义是两个或两个以上。
58.本技术中术语“至少一个”的含义是指一个或多个,本技术中术语“多个”的含义是指两个或两个以上,例如,多个第二报文是指两个或两个以上的第二报文。本文中术语“系统”和“网络”经常可互换使用。
59.还应理解,本文中所使用的术语“和/或”是指并且涵盖相关联的所列出的项目中的一个或多个项目的任何和全部可能的组合。术语“和/或”,是一种描述关联对象的关联关系,表示可以存在三种关系,例如,a和/或b,可以表示:单独存在a,同时存在a和b,单独存在b这三种情况。另外,本技术中的字符“/”,一般表示前后关联对象是一种“或”的关系。
60.还应理解,在本技术的各个实施例中,各个过程的序号的大小并不意味着执行顺序的先后,各过程的执行顺序应以其功能和内在逻辑确定,而不应对本技术实施例的实施过程构成任何限定。
61.应理解,根据a确定b并不意味着仅仅根据a确定b,还可以根据a和/或其它信息确定b。
62.还应理解,术语“包括”(也称“includes”、“including”、“comprises”和/或“comprising”)当在本说明书中使用时指定存在所陈述的特征、整数、步骤、操作、元素、和/或部件,但是并不排除存在或添加一个或多个其他特征、整数、步骤、操作、元素、部件、和/或其分组。
63.应理解,说明书通篇中提到的“一个实施例”、“一实施例”、“一种可能的实现方式”意味着与实施例或实现方式有关的特定特征、结构或特性包括在本技术的至少一个实施例中。因此,在整个说明书各处出现的“在一个实施例中”或“在一实施例中”、“一种可能的实现方式”未必一定指相同的实施例。此外,这些特定的特征、结构或特性可以任意适合的方式结合在一个或多个实施例中。
64.应理解,多线程程序中并行运行的线程是彼此独立的控制流,但不同线程中用于访问内存(为简单描述,本技术实施例将“访问内存”简写为“访存”)的指令之间可能存在逻辑关系。这里,用于访存的指令通常包括读指令和/或写指令。
65.作为示例,在基于非弱内存模型开发的多线程程序中,第一线程中用于访存的写指令1,用于将寄存器1中的值0写入(store)内存。第二线程中用于访存的读指令2,用于从内存中读取(load)值0到寄存器2。因此,该写指令1和读指令2之间存在前后的逻辑顺序关系,即写指令1将寄存器1的值0写入内存后,读指令2才可以将内存中的值0读取到寄存器中。
66.当该多线程程序的第一线程和第二线程,通过采用弱内存模型的计算机设备的两个处理核并行运行时,如果写指令1先于第一线程中位于写指令1之前的读指令或写指令被执行,这样,可能造成写指令1晚于第二线程中的读指令2的被执行。当写指令1晚于第二线程中的读指令2的被执行,则第二线程中的读指令2被执行时,内存是空的,即寄存器1中的值0还没有被写入内存。这样的话,第一线程和第二线程所执行的任务则出现了逻辑上的错误,从而可能造成程序崩溃,或者输出结果不准确等后果。这种情况,即称为第一线程中的写指令1产生了弱内存序的问题。
67.通常,程序的线程在运行时,可能发生弱内存序的情况包括:读读(loadload)、写
erasable programmable read-only memory,eeprom)、磁盘存储介质或者其他磁存储设备、或者能够用于携带或存储具有指令或数据结构形式的期望的程序代码并能够由计算机存取的任何其他介质,但不限于此。
79.一种可能的实现方式中,存储器22可以独立于处理器21存在。存储器22可以通过总线25与处理器21相连接,用于存储数据、指令或者程序代码。处理器21调用并执行存储器22中存储的指令或程序代码时,能够实现本技术实施例提供的修复访问乱序问题的方法。
80.另一种可能的实现方式中,存储器22也可以和处理器21集成在一起。
81.通信接口23,用于计算设备20与其他设备(如公有云中的网络节点等)通过通信网络连接,所述通信网络可以是以太网,无线接入网(radio access network,ran),无线局域网(wireless local area networks,wlan)等。通信接口23可以包括用于接收数据的接收单元,以及用于发送数据的发送单元。
82.输入输出接口24,用于实现用户和计算设备20的人机交互。输入输出接口24可以是鼠标,键盘、触摸屏等器件,当然不限于此。
83.作为示例,用户可以基于输入输出接口可以向计算设备提交黑名单或白名单等。
84.总线25,可以是工业标准体系结构(industry standard architecture,isa)总线、外部设备互连(peripheral component interconnect,pci)总线或扩展工业标准体系结构(extended industry standard architecture,eisa)总线等。该总线可以分为地址总线、数据总线、控制总线等。为便于表示,图2中仅用一条粗线表示,但并不表示仅有一根总线或一种类型的总线。
85.需要指出的是,图2中示出的结构并不构成对该计算设备20的限定,除图2所示部件之外,该计算设备20可以包括比图示更多或更少的部件,或者组合某些部件,或者不同的部件布置。
86.下面结合附图,对本技术实施例提供的修复弱内存序问题的方法予以说明。
87.参考图3,图3示出了本技术实施例提供的一种修复弱内存序问题的方法的流程示意图。该方法可以应用于图2所示的修复装置。该方法可以包括以下步骤:
88.s101、修复装置确定读写指令集。
89.具体的,修复装置可以在待修复代码中确定该读写指令集,该读写指令集中包括该待修复代码中的读指令和/或写指令,该读写指令集中的指令用于访存。
90.例如,读指令“ldr x1,[x0]”,表示从通用寄存器x0所指向的内存地址中读取值,并将该值写入通用寄存器x1。再例如,写指令“str x1,[x0]”,表示将通用寄存器x1中的值写入通用寄存器x0所指向的内存地址。
[0091]
为简单描述,本技术实施例在下文描述中,将“读指令和/或写指令”简称为“读写指令”。
[0092]
其中,待修复代码可以是多线程程序的源代码经编译器编译得到的中间语言。或者,该待修复代码还可以是多线程程序的源代码经编译器编译得到的汇编代码,本技术实施例对此不作具体限定。这里,编译器、中间语言的相关描述可以参考上文的描述,这里不再赘述。
[0093]
可选的,待修复代码还可以是多线程程序的源代码中的待修复模块,经编译器编译所得到的中间语言。或者,该待修复代码还可以是多线程程序的源代码中的待修复模块,
经编译器编译所得到的汇编代码,本技术实施例对此不作具体限定。
[0094]
其中,待修复模块可以是开发人员对多线程程序的源代码进行划分后,得到的多个模块中的一个模块。或者,待修复模块可以是预处理器或编译器对多线程程序的源代码进行划分后,得到的多个模块中的一个模块。本技术实施例对此不作限定。
[0095]
其中,对多线程程序的源代码进行划分,可以按照代码所能实现的功能或用途进行划分,当然不限于此。
[0096]
其中,多线程程序的源代码经划分后所得到的多个模块中,包括安全模块和非安全模块。其中,安全模块,是指该模块中的源代码经编译后得到的读写指令,不会产生弱内存序的问题。非安全模块,是指该模块中的源代码经编译后得到的读写指令,会产生弱内存序的问题。因此,该非安全模块即为上述的待修复模块。
[0097]
可选的,安全模块可以通过大量运行测试,确定其不会产生弱内存序的问题,对此不作具体限定。
[0098]
具体的,修复装置可以通过识别待修复代码中的指令,以确定该待修复代码中的读写指令,从而得到该待修复代码对应的读写指令集。
[0099]
在一种可能的实现方式中,修复装置可以以待修复代码中的函数为单位,对目标函数中的指令进行识别,以确定出该目标函数中的读写指令,从而得到该目标函数对应的读写指令集。其中,目标函数是待修复代码中的任意一个函数。应理解,待修复代码是由至少一个函数组成的。
[0100]
具体的,修复装置可以遍历目标函数中的每个指令,并对该目标函数中的每个指令进行识别,以确定出该目标函数中的读写指令,从而得到该目标函数对应的读写指令集。
[0101]
这样,当修复装置对待修复代码中的每个函数中的指令进行识别后,即可确定出该每个函数所对应的读写指令集。该每个函数所对应的读写指令集的集合,包括该待修复代码中的全部读写指令。
[0102]
可以看出,通过这种方式确定读写指令集时,待修复代码中的每个函数可以对应一个读写指令集,即待修复代码中的函数与确定出的读写指令集一一对应。或者,该待修复代码也可以对应一个读写指令集,这种情况下,该读写指令集可以是修复装置将基于每个函数确定的读写指令集进行聚合后得到的,本技术实施例对此不作具体限定。
[0103]
在另一种可能的实现方式中,修复装置可以遍历待修复代码中的指令,并对待修复代码中的指令进行识别,以确定出待修复代码中的读写指令,从而得到该待修复代码对应的读写指令集。
[0104]
可以看出,通过这种方式确定读写指令集时,待修复代码对应一个读写指令集。
[0105]
s102、修复装置基于读写指令集,确定第一类指令。
[0106]
修复装置可以基于上述确定出的读写指令集,在该读写指令集中确定第一类指令。这里,该第一类指令中的指令不会产生弱内存序问题,即第一类指令是弱内存序安全的指令。
[0107]
其中,第一类指令中的指令,可以是指令本身就不会产生弱内存序问题的指令,也可以是在预设的上下文中不会产生弱内存序问题的指令,对此不作限定。
[0108]
可选的,第一类指令可以包括读写线程间非共享变量的指令、或具有保序语义的读写指令中的至少一种。
[0109]
其中,线程间非共享变量,即为一个线程(例如第一线程)内部专用的变量,该变量不会被除第一线程之外的线程调用。这样,对于读写这一类变量的指令而言,通常不会产生弱内存序问题。
[0110]
示例性的,读写线程间非共享变量的指令,可以包括读写局部变量的指令或读写thread local指令中的至少一种。
[0111]
对于具有保序语义的读写指令而言,其本身的语义使其在执行时不会出现弱内存序的问题。
[0112]
s103、修复装置根据第一类指令,确定目标指令集,以及在目标指令集中确定目标指令。
[0113]
其中,目标指令集中的指令是上述读写指令集中、除第一类指令之外的全部指令。这样,修复装置即可上述确定出的第一类指令,在上述读写指令集中确定出目标指令集。
[0114]
进一步的,修复装置可以在目标指令集中,确定目标指令。
[0115]
在一种可能的实现方式中,修复装置可以将目标指令集中的全部指令,确定为目标指令。也就是说,修复装置对目标指令集中的所有指令全部进行修复。
[0116]
在另一种可能的实现方式中,修复装置可以基于以下优化策略中的至少一种,在目标指令集中确定目标指令。其中,优化策略用于指示需要修复弱内存序问题的读写指令类型。
[0117]
其中,修复装置可以预置有该优化策略,修复装置也可以在开始修复待修复代码时,获取用户配置的优化策略,对此不作限定。
[0118]
其中,该优化策略可以包括下文描述的第一策略-第四策略。可以理解,该第一策略-第四策略仅为示例性说明,本技术实施例不限于此。
[0119]
其中,在一种情况下,当上述的优化策略是由用户预先配置的优化策略时,用户可以通过计算设备的输入输出接口,并采用图形交互界面、命令行插入或设置配置文件等方式中的任意一种方式,向修复装置提交优化策略。作为响应,修复装置可以获取到用户配置的优化策略,并在修复待修复代码时,基于该获取到的优化策略确定目标指令。
[0120]
示例性的,以用户通过计算设备的输入输出接口,并采用设置配置文件的方式向修复装置提交优化策略为例。通常,用户可以将预先配置的优化策略文件放入修复装置的根目录中,并修改该文件的后缀格式,从而实现在修复装置中设置优化策略的配置文件。这样,修复装置在执行本技术实施例所提供的方法时,即可以按照配置文件指示的优化策略,在目标指令集中确定目标指令,并对其进行修复。
[0121]
当然,上述的优化策略还可以包括用户基于自身的需求自定义配置的第五策略,本技术实施例对此不作限定。
[0122]
这种情况下,修复装置可以预先获取用户自定义配置的第五策略,并将该第五策略添加至上述的优化策略中。这样,修复装置即可在修复待修复代码时,基于包括该第五策略的优化策略来确定目标指令。这里,修复装置预先获取用户自定义配置的第五策略的过程,可以参考上文中修复装置获取由用户预先配置的优化策略的描述,这里不予赘述。
[0123]
在另一种情况下,修复装置中预置有上述优化策略。这样,修复装置可以根据预置的优化策略,在修复待修复代码的过程中确定目标指令,当然,修复预装置也可以将所预置的优化策略作为待选优化策略,这样,修复装置即可在开始修复待修复代码时,接收用户输
入的指示信息,并基于该指示信息所指示的优化策略来确定目标指令。这里,该指示信息用于指示用户从待选优化策略中选择的优化策略。
[0124]
应理解,修复装置中预置的优化策略可以包括修复装置预先获取的用户自定义配置的第五策略,当然,修复装置也可以在修复待修复代码时,获取用户自定义配置的第五策略,对此不作限定。下面以修复装置在修复待修复代码时,获取用户自定义配置的第五策略为例进行说明。
[0125]
示例性的,参考图4a,图4a示出了修复装置基于图形交互界面获取用户从待选优化策略中选择的优化策略的示意图。如图4a中的(a)所示,修复装置可以在开始准备修复待修复代码时,或者在开始编译多线程程序的源代码时,通过计算设备的显示界面41(例如显示器)上的对话框411显示选项:第一策略、第二策略、第三策略、第四策略以及自定义优化策略等选项,以实现向用户询问修复待修复代码时需要使用的优化策略。其中,第一策略、第二策略、第三策略以及第四策略是修复装置预置的优化策略。其中,自定义优化策略是需要用户即时提交的优化策略。
[0126]
如图4a中的(a)所示,当用户通过控制鼠标(或者键盘)选中选项“第一策略”和“第二策略”,从而实现向修复装置发送用于指示“第一策略”和“第二策略”的指示信息,这样,修复装置即可基于该指示信息,确定出用户所选择的优化策略为“第一策略”和“第二策略”。这样,修复装置即可基于用户所选择的优化策略,在目标指令集中确定目标指令,并对其进行修复。
[0127]
如图4a中的(b)所示,当用户通过控制鼠标(或者键盘)选中选项“自定义优化策略”时,用户即可通过控制鼠标(或者键盘),在如图4a中的(c)所示的对话框412中,上传用户自己预先自定义配置的策略。例如,用户可以先通过操作鼠标(或者键盘),通过点击“浏览”图标查找到自定义配置的策略的存储目录“aa/bb/cc/”。然后,用户可以通过操作鼠标(或者键盘)点击“上传”图标,以上传用户自定义配置的策略。作为响应,修复装置即接收到用户上传的自定义配置的策略。这样,修复装置可以基于该自定义配置的策略,在目标指令集中确定目标指令,并对其进行修复。
[0128]
可以看出,通过允许用户自定义配置策略,以及允许用户从待选优化策略中自由选择优化策略,使得本技术实施例提供的方法的应用更加灵活。
[0129]
应理解,修复装置是在本技术实施例描述的技术方案执行之前,获取用户配置的优化策略。这样,修复装置即可通过配置好的优化策略,在执行本技术实施例提供的方法的过程中,对优化策略所指示类型的读写指令进行修复。
[0130]
下面示例性的对第一策略-第四策略予以说明:
[0131]
第一策略:修复装置可以将目标指令集中属于白名单的读写指令,确定为目标指令,或者,修复装置可以将目标指令集中,除黑名单中的读写指令之外的读写指令,确定为目标指令。
[0132]
其中,上述的白名单和黑名单,可以是待修复代码中函数的黑名单和白名单,可以是待修复代码中不同功能模块的黑名单和白名单,对此不作限定。
[0133]
下面,以上述的白名单和黑名单,是待修复代码中函数的黑名单和白名单为例进行说明。
[0134]
其中,函数的黑名单,通常包括待修复代码中的安全函数和/或热点函数等函数。
[0135]
这里,安全函数,通常可以是经普通编译后得到的可执行程序被运行后,没有发生弱内存序问题的函数,或者,安全函数可以是源代码中不包括共享变量的函数,等等,对此不作限定。由于安全函数通常不会产生弱内存序问题,因此,修复装置无需对安全函数进行弱内存序问题的修复。
[0136]
热点函数,通常是被程序频繁调用的函数。例如,函数a被程序调用的次数大于等于预设阈值,则该函数a为热点函数。由于对指令的弱内存序问题的修复,是通过在该指令前插入内存屏障指令来实现的。因此对于热点函数而言,由于其被频繁调用,因此当在热点函数中插入内存屏障指令,会导致程序的运行性能下降。因此,对于热点函数,修复装置即不对其进行弱内存序问题的修复。
[0137]
当然,函数的黑名单里的热点函数,也可以是预先通过上述确定安全函数的方式,确定其不会出现弱内存序问题热点函数。
[0138]
函数白名单,通常包括待修复代码中,除上述热点函数和/或安全函数之外的函数。对于这一类函数,修复装置可以对其进行弱内存序问题的修复。
[0139]
应理解,修复装置可以预置上述的函数黑名单和/或函数白名单,修复装置也可以获取用户预先配置的函数黑名单和/或函数白名单,对此不作限定。
[0140]
当上述的函数黑名单和/或函数白名单是用户预先配置的,则用户可以通过计算设备的输入输出接口,并通过图形交互界面、命令行插入或设置配置文件等方式中的任意一种方式,将预先配置的函数黑名单和/或函数白名单提交至修复装置。作为响应,修复装置即可获取到用户配置的函数黑名单和/或函数白名单。这里,修复装置获取用户配置的函数黑名单和/或函数白名单的过程,可以参考修复装置获取用户自定义优化策略的过程的描述,不再赘述。
[0141]
第二策略:修复装置可以将目标指令集中具有上下文依赖关系的读写指令中,仅作为依赖的读写指令,确定为目标指令。
[0142]
可选的,修复装置可以对目标指令集中的指令进行分析,并根据目标指令集里读写指令的上下文依赖关系,确定仅作为依赖的读写指令。这里,仅作为依赖的读写指令,是指不依赖目标指令集中其他读写指令的指令。
[0143]
作为示例,如果目标指令集中包括如下指令:
[0144]
指令1:ldr x0,[s1];
[0145]
指令2:str x0,[s2];
[0146]
其中,指令1“ldr x0,[s1]”表示从寄存器s1所指示的内存地址中读到寄存器x0。指令2“str x0,[s2]”表示将寄存器x0中的值写入寄存器s2所指示的内存地址。可以看出,当指令1没有被执行时,即寄存器x0中的值没有被从寄存器s1所指示的内存地址中读到时,则不能执行指令2,以将寄存器x0中的值写入寄存器s2所指示的内存地址。也就是说,指令1和指令2是具有依赖关系的指令,且指令1是指令2的依赖。即,指令2的执行,依赖于指令1的执行。这种情况下,当指令1的执行不依赖于目标指令集中的其他读写指令时,修复装置可以确定指令1是仅作为依赖的读写指令。
[0147]
对于具有上下文依赖关系,且依赖于其他指令执行的读写指令,这一类指令通常不会发生弱内存序问题。因此,修复装置对于这一类指令通常可以不予修复。
[0148]
第三策略:修复装置可以将目标指令集中除与专用寄存器有关的读写指令之外的
读写指令,确定为目标指令。
[0149]
其中,专用寄存器通常是指只用于特定指令或场合的寄存器。例如,该专用寄存器可以是浮点寄存器。这里,浮点寄存器是用于存储浮点数的寄存器。
[0150]
以专用寄存器是浮点寄存器为例,修复装置可以通过识别读写指令中的寄存器的名称,以确定该寄存器是否是浮点寄存器。当该读写指令中的寄存器是浮点寄存器,则修复装置可以确定该读写指令是对浮点寄存器进行操作的读写指令。
[0151]
由于专用寄存器通常不会被用于读写全局控制变量,因此对专用寄存器进行操作的读写指令,通常不会产生弱内存序的问题。因此,对专用寄存器进行操作的读写指令,修复装置通常可以不对其进行修复。
[0152]
第四策略:修复装置可以将目标指令集中除与输入输出参数有关的读写指令之外的读写指令,确定为目标指令。
[0153]
其中,输入输出参数包括调用函数时需要输入的参数,以及函数的返回值。
[0154]
示例性的,当通用寄存器x0是用于存储函数的返回值的寄存器,如果目标指令集中的指令如下:
[0155]
b malloc;
[0156]
str x11,[x0];
[0157]
其中,“b”表示指令类相为调用函数的指令,“malloc”是用于申请内存的函数名称。则指令“b malloc”表示调用函数malloc。当函数“malloc”被执行后,“malloc”返回的内存地址将被写入通用寄存器x0。这时,指令“str x11,[x0]”即用于表示将寄存器“x11”中的值写入通用寄存器x0所指示的内存地址,该内存地址及为“malloc”返回的内存地址。这种情况下,指令“str x11,[x0]”即为与输入输出参数有关的读写指令。
[0158]
通常,在类似这种场景下,对于与输入输出参数有关的读写指令,不会发生弱内存序问题,因此修复装置可以对其不做修复。
[0159]
需要说明的是,在修复装置基于第四策略确定目标指令时,还可以基于目标指令集中指令的上下文逻辑关系确定目标指令,对此不作赘述。
[0160]
需要说明的是,当修复装置采用的优化策略,是上述第一策略-第四策略的任意组合策略时,修复装置可以预置该组合策略中的多个策略的优先级。这样,当同一个读写指令基于两个不同的策略产生了相反的结果时,修复装置可以基于该优先级,通过优先级高的策略处理该读写指令。其中,优先级用于指示策略的优先等级,优先等级高的策略优先于优化等级低的策略被使用。
[0161]
示例性的,当组合策略是上述第二策略和第三策略,如果指令1是仅作为依赖的指令,按照第二策略的指示,修复装置应对指令1予以修复。同时,如果指令1是对于浮点寄存器进行读写的指令,那么按照第三策略的指示,修复装置应对指令1不予修复。这种情况下,即组合策略中的不同策略在同一条指令上产生了相反的结果。这时,如果组合策略中的第二策略的优先级高于第三策略,则修复装置基于第二策略,将指令1确定为目标指令,并对其进行修复。
[0162]
s104、修复装置在上述确定的目标指令的前一条读写指令和该目标指令之间插入内存屏障指令。
[0163]
修复装置在确定目标指令后,上述确定的目标指令的前一条读写指令和该目标指
令之间插入内存屏障指令,从而实现了待修复代码中指令的弱内存序问题的修复。
[0164]
其中,该内存屏障指令用于指示,该内存屏障指令之前的读写指令执行结束后,再执行目标指令。
[0165]
作为示例,如果目标指令为指令1,目标指令的前一条读写指令为指令2。则当修复装置在指令1和指令2之间插入内存屏障指令。该内存屏障指令用于指示指令1在指令2之后执行。
[0166]
至此,本技术实施例提供了一种修复弱内存序问题的方法,该方法在多线程程序源代码编译的过程中,通过对待修复指令进行分类,以确定出目标指令集。然后,进一步通过优化策略在目标指令集中确定需要插入内存屏障指令的目标指令,以使目标指令能够按照程序本身要求的顺序去执行。通过该方法,修复装置可以自动的修复多线程程序的弱内存序问题。
[0167]
可选的,参考图4b,在本技术实施例提供的另一种修复弱内存序问题的方法中,上述的s102-s103可以用下述步骤s202替换。
[0168]
s202、修复装置基于优化策略,对读写指令集中的指令进行分类,以确定目标指令。
[0169]
其中,该读写指令集即为修复装置在s101中所确定的读写指令集。
[0170]
其中,优化策略用于指示需要修复弱内存序问题的读写指令类型。该优化策略的说明可以参考上文中有关优化策略的描述,这里不予赘述。
[0171]
具体的,修复装置可以基于上述的优化策略,在步骤s101所确定的读写指令集中,将读写指令按照优化策略划分为需要插入内存屏障指令的读写指令和不需要插入内存屏障指令的读写指令。然后,修复装置将需要插入内存屏障指令的读写指令确定为目标指令。
[0172]
这样,在多线程程序源代码编译的过程中,通过本技术实施例提供的修复弱内存序问题的方法,可以直接通过优化策略对待修复指令进行分类,从而确定出需要插入内存屏障指令的目标指令,这样,即能保证目标指令按照程序本身要求的顺序去执行。通过该方法,修复装置可以实现自动的修复多线程程序的弱内存序问题。
[0173]
为了更容易的理解对本技术实施例所提供的方法,下面以在gnu编译器套件(gnu compiler collection,gcc)中应用本技术实施例提供的修复弱内存序问题的方法,修复多线程程序的弱内存序问题为例进行说明。
[0174]
其中,gcc支持通过c、c 或fortran等高级计算机语言开发的程序源代码的编译。gcc编译程序源代码的工作过程包括:预处理(pre-processing)、编译(compiling)、汇编(assembling)以及链接(linking)。本技术实施例提供的修复弱内存序问题的方法可以应用在编译阶段。
[0175]
在gcc在编译阶段,将经预处理的多线程程序源代码编译后,可以得到编译器的中间语言(例如暂存器转换语言(register transformation language,rtl)表达式)。然后,gcc可以通过final模块将优化后的中间语言,输出为汇编代码。
[0176]
通常,final模块以函数为单元,将中间语言输出为汇编代码。具体的,final模块通过final_start_function,final以及final_end_function接口,将中间语言输出为汇编代码。
[0177]
其中,final_start_function接口,用于初始化函数的状态。例如分析中间语言中
函数里指令的数量,以及确定insn语句的数量等,不作赘述。
[0178]
final接口,用于将中间语言输出为汇编代码。本技术实施例提供的修复弱内存序问题的方法(例如图3或图4b所示的修复弱内存序问题的方法)即可在这一阶段中执行。具体的,修复装置可以通过final接口执行上述s101-s104所述的方法,在目标指令前插入内存屏障指令。然后,final接口调用output_asm_insn函数,将insn语句输出为汇编代码。
[0179]
其中,一个insn语句中包含的多个汇编指令,每条汇编指令的长度一般为4。由于在初始化函数状态时确定出了insn语句的数量和指令的数量。因此,final接口通常已经确定一个insn语句的长度。
[0180]
然而,修复装置通过final接口修复读写指令时,会在目标指令前插入内存屏障指令。因此,修复指令会改变insn语句的长度。这种情况下,final接口在输出成汇编代码前,final_start_functio接口需要对原本的获取insn语句长度的过程(如get_attr_length)予以对应处理,以获取到插入内存屏障指令后的insn语句的长度。例如通过函数调用来减少insn语句中的指令的数量,以控制insn语句的长度,等等,对此不做限定。
[0181]
最终,final_end_function用于清理将中间语言输出为汇编代码所使用的资源。
[0182]
然后,gcc继续对修复完成的汇编代码进行汇编以及链接,从而输出可执行的程序代码。这里,本技术实施例对gcc的具体工作过程不作详细赘述。应理解,gcc最终输出的可执行的程序代码,即为修复了弱内存序的程序代码。
[0183]
综上,本技术实施例提供了一种修复弱内存序问题的方法,该方法在多线程程序源代码编译的过程中,通过对待修复指令进行分类,以确定出目标指令集。然后,进一步通过优化策略在目标指令集中确定需要插入内存屏障指令的目标指令,以使目标指令能够按照程序本身要求的顺序去执行,从而实现了自动的修复多线程程序的弱内存序的问题。通过本技术实施例提供的方法来修复多线程程序的弱内存序问题,大大提高了程序弱内存序问题修复的效率。
[0184]
另外,本技术实施例中以函数为单位来识别并修复待修复代码中的弱内存序问题,从而使得本技术实施例所提供的方法可以应用于大规模的多线程程序的弱内存序问题的修复,进而提高了本技术实施例所提供方法的实用性。
[0185]
上述主要从方法的角度对本技术实施例提供的方案进行了介绍。为了实现上述功能,其包含了执行各个功能相应的硬件结构和/或软件模块。本领域技术人员应该很容易意识到,结合本文中所公开的实施例描述的各示例的单元及算法步骤,本技术能够以硬件或硬件和计算机软件的结合形式来实现。某个功能究竟以硬件还是计算机软件驱动硬件的方式来执行,取决于技术方案的特定应用和设计约束条件。专业技术人员可以对每个特定的应用来使用不同方法来实现所描述的功能,但是这种实现不应认为超出本技术的范围。
[0186]
本技术实施例可以根据上述方法示例对修复装置进行功能模块的划分,例如,可以对应各个功能划分各个功能模块,也可以将两个或两个以上的功能集成在一个处理模块中。上述集成的模块既可以采用硬件的形式实现,也可以采用软件功能模块的形式实现。需要说明的是,本技术实施例中对模块的划分是示意性的,仅仅为一种逻辑功能划分,实际实现时可以有另外的划分方式。
[0187]
如图5所示,图5示出了本技术实施例提供的一种修复装置50的结构示意图。修复装置50可以用于执行上述的修复弱内存序问题的方法中,例如用于执行图3所示的方法。其
中,修复装置50可以包括确定单元51和插入单元52。
[0188]
确定单元51,用于在待修复代码中确定读写指令集;以及,用于对该读写指令集中的指令进行分类,以确定目标指令。其中,该读写指令集包括待修复代码中的读指令和/或写指令,该读写指令集中的指令用于访问内存。插入单元52,用于在目标指令的前一条读写指令和目标指令之间插入内存屏障指令。
[0189]
作为示例,结合图3,确定单元51可以用于执行s101-s103,插入单元52可以用于执行s104。
[0190]
可选的,确定单元51,具体用于在上述读写指令集中确定第一类指令;以及,用于根据该第一类指令,确定目标指令。其中,该第一类指令中的指令是弱内存序安全的指令,该目标指令是上述读写指令集中、除该第一类指令之外的指令。
[0191]
作为示例,结合图3,确定单元51可以用于执行s102-s103。
[0192]
可选的,确定单元51,具体用于基于上述第一类指令,确定目标指令集;以及,用于基于优化策略,在该目标指令集中确定目标指令,其中,该目标指令集包括上述读写指令集中,除第一类指令之外的全部指令。该优化策略用于指示需要修复弱内存序问题的读写指令类型。
[0193]
作为示例,结合图3,确定单元51可以用于执行s103。
[0194]
可选的,确定单元51具体用于:基于优化策略,对上述读写指令集中的指令进行分类,以确定目标指令。该优化策略用于指示需要修复弱内存序问题的读写指令类型。
[0195]
可选的,上述优化策略包括以下策略中的至少一种:第一策略、将目标指令集中属于白名单中的读写指令,确定为目标指令;或者,将目标指令集中,除黑名单中的读写指令之外的读写指令,确定为目标指令。第二策略、将目标指令集中具有上下文依赖关系的读写指令中,仅作为依赖的读写指令,确定为目标指令。第三策略、将目标指令集中除与专用寄存器有关的读写指令之外的读写指令,确定为目标指令。第四策略、将目标指令集中除与输入输出参数有关的读写指令之外的读写指令,确定为目标指令。
[0196]
可选的,修复装置50还包括:获取单元53,用于获取用户配置的第五策略。添加单元54,用于将该第五策略添加至上述的优化策略中。
[0197]
可选的,修复装置50还包括:接收单元55,用于在确定单元51确定目标指令之前,接收指示信息,其中,该指示信息用于指示用户从待选优化策略中选择上述的优化策略。
[0198]
可选的,上述第一类指令包括读写线程间非共享变量的指令、或具有保序语义的读写指令中的至少一种。
[0199]
可选的,修复装置50还包括:识别单元56,用于对目标函数中的指令进行识别,以确定上述读写指令集。其中,该目标函数是上述待修复代码中的任意一个函数。
[0200]
作为示例,结合图3,识别单元56可以用于执行s101。
[0201]
可选的,上述待修复代码是多线程程序的源代码经编译器编译得到的中间语言,或者,上述待修复代码是多线程程序的源代码经编译器编译得到的汇编代码。
[0202]
关于上述可选方式的具体描述可以参见前述的方法实施例,此处不再赘述。此外,上述提供的任一种修复装置50的解释以及有益效果的描述均可参考上述对应的方法实施例,不再赘述。
[0203]
作为示例,结合图2,修复装置50中的确定单元51、插入单元52、添加单元54以及识
别单元56,可以通过图2中的处理器21执行图2中的存储器22中的程序代码实现。获取单元53和接收单元55可以通过图2中的输入输出接口24或通信接口25实现。
[0204]
本技术实施例还提供一种芯片系统60,如图6所示,该芯片系统60包括至少一个处理器和至少一个接口电路。作为示例,当该芯片系统60包括一个处理器和一个接口电路时,则该一个处理器可以是图6中实线框所示的处理器61(或者是虚线框所示的处理器61),该一个接口电路可以是图6中实线框所示的接口电路62(或者是虚线框所示的接口电路62)。当该芯片系统60包括两个处理器和两个接口电路时,则该两个处理器包括图6中实线框所示的处理器61和虚线框所示的处理器61,该两个接口电路包括图6中实线框所示的接口电路62和虚线框所示的接口电路62。对此不作限定。
[0205]
处理器61和接口电路62可通过线路互联。例如,接口电路62可用于接收信号(例如获优化策略等)。又例如,接口电路62可用于向其它装置(例如处理器61)发送信号。示例性的,接口电路62可读取存储器中存储的指令,并将该指令发送给处理器61。当该指令被处理器61执行时,可使得修复装置执行上述实施例中的各个步骤。当然,该芯片系统60还可以包含其他分立器件,本技术实施例对此不作具体限定。
[0206]
本技术另一实施例还提供一种计算机可读存储介质,该计算机可读存储介质中存储有指令,当指令在修复装置上运行时,该修复装置执行上述方法实施例所示的方法流程中该修复装置执行的各个步骤。
[0207]
在一些实施例中,所公开的方法可以实施为以机器可读格式被编码在计算机可读存储介质上的或者被编码在其它非瞬时性介质或者制品上的计算机程序指令。
[0208]
图7示意性地示出本技术实施例提供的计算机程序产品的概念性局部视图,该计算机程序产品包括用于在计算设备上执行计算机进程的计算机程序。
[0209]
在一个实施例中,计算机程序产品是使用信号承载介质70来提供的。该信号承载介质70可以包括一个或多个程序指令,其当被一个或多个处理器运行时可以提供以上针对图3描述的功能或者部分功能。因此,例如,参考图3中s101~s104的一个或多个特征可以由与信号承载介质70相关联的一个或多个指令来承担。此外,图7中的程序指令也描述示例指令。
[0210]
在一些示例中,信号承载介质70可以包含计算机可读介质71,诸如但不限于,硬盘驱动器、紧密盘(cd)、数字视频光盘(dvd)、数字磁带、存储器、只读存储记忆体(read-only memory,rom)或随机存储记忆体(random access memory,ram)等等。
[0211]
在一些实施方式中,信号承载介质70可以包含计算机可记录介质72,诸如但不限于,存储器、读/写(r/w)cd、r/w dvd、等等。
[0212]
在一些实施方式中,信号承载介质70可以包含通信介质73,诸如但不限于,数字和/或模拟通信介质(例如,光纤电缆、波导、有线通信链路、无线通信链路、等等)。
[0213]
信号承载介质70可以由无线形式的通信介质73(例如,遵守ieee 1902.11标准或者其它传输协议的无线通信介质)来传达。一个或多个程序指令可以是,例如,计算机可执行指令或者逻辑实施指令。
[0214]
在一些示例中,诸如针对图3描述的修复装置可以被配置为,响应于通过计算机可读介质71、计算机可记录介质72、和/或通信介质73中的一个或多个程序指令,提供各种操作、功能、或者动作。
[0215]
应该理解,这里描述的布置仅仅是用于示例的目的。因而,本领域技术人员将理解,其它布置和其它元素(例如,机器、接口、功能、顺序、和功能组等等)能够被取而代之地使用,并且一些元素可以根据所期望的结果而一并省略。另外,所描述的元素中的许多是可以被实现为离散的或者分布式的组件的、或者以任何适当的组合和位置来结合其它组件实施的功能实体。
[0216]
在上述实施例中,可以全部或部分地通过软件、硬件、固件或者其任意组合来实现。当使用软件程序实现时,可以全部或部分地以计算机程序产品的形式来实现。该计算机程序产品包括一个或多个计算机指令。在计算机上和执行计算机执行指令时,全部或部分地产生按照本技术实施例的流程或功能。计算机可以是通用计算机、专用计算机、计算机网络、或者其他可编程装置。计算机指令可以存储在计算机可读存储介质中,或者从一个计算机可读存储介质向另一个计算机可读存储介质传输,例如,计算机指令可以从一个网站站点、计算机、服务器或者数据中心通过有线(例如同轴电缆、光纤、数字用户线(digital subscriber line,dsl))或无线(例如红外、无线、微波等)方式向另一个网站站点、计算机、服务器或数据中心进行传输。计算机可读存储介质可以是计算机能够存取的任何可用介质或者是包含一个或多个可以用介质集成的服务器、数据中心等数据存储设备。可用介质可以是磁性介质(例如,软盘、硬盘、磁带),光介质(例如,dvd)、或者半导体介质(例如固态硬盘(solid state disk,ssd))等。
[0217]
以上所述,仅为本发明的具体实施方式,但本发明的保护范围并不局限于此,任何熟悉本技术领域的技术人员在本发明揭露的技术范围内,可轻易想到变化或替换,都应涵盖在本发明的保护范围之内。因此,本发明的保护范围应以所述权利要求的保护范围为准。
再多了解一些

本文用于企业家、创业者技术爱好者查询,结果仅供参考。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

相关文献