没有合适的资源?快使用搜索试试~ 我知道了~
Journal of Systems Architecture 116(2021)102135在开源RISC-V评估平台中使用虚拟原型进行弗拉基米尔·赫尔特a,b,丹尼尔·格罗瑟b,c,索伦·坦普尔a,罗尔夫·德雷克斯勒a,ba德国不来梅市不来梅大学计算机科学学院bc奥地利林茨约翰内斯开普勒大学复杂系统研究所A B标准最近,虚拟原型(VP)被引入新兴的RISC-V指令集架构(ISA),并成为不断增长的RISC-V生态系统的重要组成部分。VP的一个核心组件是指令集模拟器(ISS)。VP应提供高仿真性能,同时提高产量 准确的结果,这是两个相互矛盾的要求。为了解决这个问题,我们提出了一个高效的基于VP的自适应仿真,该仿真是为RISC-V ISA量身定制的,并允许在运行时无缝切换ISS中的精度设置。这使得能够选择性地尽可能快地模拟应用程序,并根据需要尽可能准确。在本文中,我们专注于不同的精度设置的性能影响,并留下未来工作的精度结果的评估。我们的RISC-V实验使用了基于裸机和操作系统的基准测试,证明了在ISS中使用基于JIT的设置可以实现高达543倍的速度提升1. 介绍RISC-V [1,2]是一种开放且免版税的指令集架构(ISA),具有非常模块化的设计,近年来获得了巨大的发展势头。RISC-V成为物联网(IoT)等多个应用中嵌入式系统的游戏规则改变者 构建高度专业化的解决方案。除了彻底的功能验证外,性能评估和优化对于满足特定应用程序的需求至关重要。因此,主要采用基于模拟的方法。RISC-V生态系统提供了几个模拟器,可以在设计流程的早期实现软件执行。 特别是,虚拟样机(VP)在这里发挥了非常重要的作用[3,4]。虚拟样机本质上是整个硬件平台,主要在SystemC TLM(事务级建模)中创建[5]。 VP的一个核心组件是指令集模拟器(ISS),它是处理器的抽象模型。通过集成适当的时序模型,可以使用VP 进行绩效评估。一般来说,VP应该提供高仿真性能(处理复杂的SW),同时产生准确的结果(进行性能评估和优化),这是两个相互冲突的要求。为了解决这个问题,一种常见的方法是构建两个(或更多个)单独的VP模型,准确度设置,并相应地使用它们。一个快速的VP模型来执行功能验证,一个准确的VP模型来执行性能评估。然而,当仅需要准确地分析SW的(一小部分)时(例如,仅执行Linux操作系统中的特定内核模块,或者与外围设备的特定重复交互),这种方法变得非常低效。此外,由于稳定上升的(SW)复杂性,被进一步放大。因此,构建高效的解决方案变得越来越重要,这些解决方案可以在运行时按需调整VP中的精度设置。在本文中,我们提出了一个高效的基于VP的自适应模拟量身定制的RISC-V,允许无缝切换精度设置在ISS在运行时。 这使得能够选择性地模拟 应用程序尽可能快,并尽可能准确。用于切换的配置,即在执行期间的哪个点执行特定切换,由用户提供。 它可以嵌入到应用程序中,也可以传递给ISS。我们的方法允许在ISS中的基于高速即时(JIT)编译的设置与基于周期准确(CA)解释器的设置之间进行缩放,并为基于SystemC的VP量身定制。精心设计的接口允许定期与SystemC内核同步,并在ISS中收集所需的定时信息我们用一个这项工作得到了德国联邦教育研究部(BMBF)在VerSys项目中的部分支持,合同号为01IW19001。在Scale4Edge项目中,16ME 0127。*通讯作者:德国不来梅大学计算机科学研究所电子邮件地址:vherdt@uni-bremen.de(V. Herdt),daniel. jku.at(D.Große),tempel@uni-bremen.de(S.Tempel),drechsler@uni-bremen.de(R. Drechsler)。https://doi.org/10.1016/j.sysarc.2021.102135接收日期:2020年12月22日;接收日期:2021年3月27日;接受日期:2021年3月31日2021年4月9日网上发售1383-7621/© 2021作者。由爱思唯尔公司出版这是CC BY许可下的开放获取文章(http://creativecommons.org/licenses/by/4.0/)。可在ScienceDirect上获得目录列表系统架构杂志期刊主页:www.elsevier.com/locate/sysarcV. Herdt等人Journal of Systems Architecture 116(2021)1021352用于JIT和基于解释器的设置的统一定时接口,以简化切换。此外,ISS被设计为在切换之间保持一致的单个执行状态上工作。 因此,切换是一个非常轻量级的操作,可以以最小的性能开销执行。此外,切换可能发生在程序执行期间的任意点。在本文中,我们专注于不同的精度设置的性能影响,并留下准确性结果的评估,为未来的工作。我们的RISC-V实验,采用裸金属以及基于Zephyr和Linux的基准测试,证明了我们方法的有效性。他们显示,高达543倍的速度-在ISS中使用基于JIT的设置是可能的。据我们所知,我们的解决方案是唯一免费提供的基于SystemC的VP,能够引导Linux。1纸结构这篇期刊论文包括并扩展了我们以前的会议论文[6]中发表的材料。我们首先在下一段中概述本文的新贡献。在第2节中讨论了相关工作之后,我们将在第3节中回顾SystemC TLM的基本背景信息。接下来,我们将介绍基于VP的RISC-V自适应仿真方法,该方法允许在运行时无缝切换精度设置(第4节)。在第5节中,我们将继续提供有关JIT编译器后端以及与基于VP的模拟集成的更多细节。然后,第6节介绍了我们的实验评估和获得的结果。最后,对全文进行了总结 第7节概述了今后的工作。新的贡献与我们以前的会议论文[6]相比,我们已经包括了大量的扩展和新材料。我们通过添加关于基于解释器的设置的新描述和扩展基于JIT的设置的描述以及提供关于在这些执行设置之间切换的更全面的讨论来增强主要的第4我们添加了新的第5节,描述了我们的JIT编译器后端以及与基于VP的模拟的集成。其中包括一个详细的RISC-V概述示例,用于说明,以及在基于VP的仿真环境中对JIT性能优化的全面描述。 我们扩展了第6.1节实验中的性能评估,以包括基于Zephyr和Linux操作系统的基准测试。我们还对结果进行了更深入的讨论。我们更新并扩展了相关工作的讨论(第2节)。2. 相关工作考虑到RISC-V,存在许多模拟器,例如参考模拟器SPIKE [7],RISCV-QEMU [8],RV 8 [9]或Ren- ode [10]。它们在实现技术和预期用例方面有所不同,从主要的纯CPU仿真(SPIKE,RV8)到全系统仿真(QEMU),甚至支持嵌入式系统的多节点网络(Renode)。然而,它们主要是为了尽可能快地模拟而设计的,因此很难扩展到提供CA性能评估。一个可以提供准确性能评估结果的全系统模拟器,最近得到了RISC-V的支持,是gem 5[11,12]。 然而,gem 5不支持基于JIT的技术,因此性能显着降低相比,高速模拟器。此外,没有一个RISC-V模拟器支持在运行时切换定时精度设置。我们的开源RISC-V VP [13],在1访问https://github.com/agra-uni-bremen/riscv-vp,在GitHub上找到我们的开源RISC-V VP。此外,请访问http://www.systemc-verification.org/risc-v,了解我们最新的RISC-V相关方法。SystemC TLM是为RISC-V实现有效的基于VP的运行时自适应仿真的坚实基础。作为此用例基础的可行替代方案是DBT-RISE [14]框架和ETISS[15] ISS也是基于SystemC集成而设计的。关于DBT-RISE,提供了在SystemC TLM中实现的示例VP平台[16],其集成了RISC-V ISS [17]。RISC-V的另一个SystemC TLM模拟器是RISC-V- TLM [18],目前正在积极开发中,支持32位RISC-V ISA和FreeRTOS操作系统。商业VP工具,例如Synopsys Virtualizer或Mentor Vista,可能支持RISC-V与快速准确的时序模型的结合,但它们的实现是专有的。最后,形式化RISC-V ISA语义,例如SAIL [19]和GRIFT [20],它们也提供或可以生成模拟器后端。然而,它们仅提供有限的仿真性能,并且不是为时序精确仿真而设计的。除了RISC-V之外,使用可配置模拟器的一般想法并不新鲜。例如,[21]提出了一个用于PowerPC架构的(全系统)模拟器,可以通过编译时标志和命令行参数进行广泛配置。在[22]中,描述了一种基于JIT的重新实现,以加速纯功能模拟。细粒度配置的模拟器(通过生成不同的模型),以满足应用程序的具体需求进行了讨论在[23]中。[24]提出了一种自适应仿真,可以学习近似的时序模型(结合基于JIT的执行),以提供近似的时序结果。然而,据我们所知,在CA和为RISC-V量身定制的基于高性能JIT的执行之间进行缩放的基于VP的运行时自适应模拟是不可用的。已经提出了一些方法,运行时自适应模拟的背景下,虚拟样机。[25]建议在不同的抽象层次上创建TLM(总线)模型,并在它们之间切换在运行时(基于用户提供的配置),以获得快速和准确的结果。[26]在概念上类似,但除了性能评估外,还考虑了功耗建模。这些方法是对我们方法的补充,因为它们考虑了而我们专注于国际空间站其他方法利用运行时自适应仿真在基于ISS和基于RTL的[27]以及门级仿真[28]之间切换,以实现快速准确的故障注入。 这些方法在与我们不同的抽象级别上运行。 在VP级别之外,自适应技术和重新配置已经被考虑用于例如优化DRAM架构的缓存行为[29]。 或者在保持功率要求的同时提高片上网络的性能[30]。几种方法专注于提高一般SystemC和TLM性能,例如通过利用自动化抽象[31],(基于GPU的)并行化[32,33]和优化的数据结构[34]。这些方法可以加快VP为基础的模拟一般,是我们的方法的补充。许多最新的最先进的性能评估技术集中在源级时序仿真(SLTS)上,以实现高速性能评估[35SLTS的工作原理是使用通常通过静态分析获得的定时信息来插装应用程序源代码,然后主机编译插装的源代码,并在没有任何仿真层的情况下本机执行所得的二进制文件。然而,由于源级抽象,为外围设备提供准确的模型并准确地考虑复杂的HW/SW交互(如中断)是非常困难的。其他最近的方法利用基于动态二进制转换(DBT)的技术(以将客户机指令动态转换为x86_x64)。请注意,在这种情况下,DBT类似于JIT编译。 论文[39,40]讨论了QEMU [41]和SystemC内核的组合。然而,这些方法要么只能提供粗略的性能估计,要么会在QEMU和SystemC之间产生显著的同步开销,并失去SystemC的确定性V. Herdt等人Journal of Systems Architecture 116(2021)1021353仿真另一种基于DBT的方法是[42],它将时序模型与基于DBT的执行引擎集成,以获得接近CA的结果。 [43][44]和[45]在概念上是相似的,但使用 QEMU和OVP [46]分别作为执行后端。在[47]中,QEMU被扩展到考虑无序处理器的时序效应。然而,这些方法主要关注纯基于CPU的基准测试(因此它们忽略了外围设备),并且固有地遭受准确性与性能的权衡。为了获得准确的结果,基于DBT的模拟需要大量的仪器(例如,以跟踪流水线、分支预测和缓存效果),这导致显著的性能开销。3. 背景:SystemC和TLMSystemC TLM是一个经过行业验证的用于创建VP的建模标准[3]。SystemC不是一种新语言,而是一个C++类库,其中包括一个事件驱动的仿真内核[5]。 SystemC设计的结构是用端口和模块来描述的,而行为是在由事件触发的进程中建模的。SystemC模块之间的通信使用TLM事务进行抽象,代价是时序精度,但仿真速度显著提高,即与RTL仿真相比高达1000倍。事务对象基本上由命令(例如读/写)和要传输的数据(有效载荷)组成。事务在总线系统上根据它们的地址从发起者路由到目标套接字,这都在SystemC TLM-2.0标准中定义。通常使用两种优化技术来提高SystemC的仿真性能:直接内存接口(Direct Memory Interface,简称DMA)和时间量子(Time Quantum,简称TQ)。对于特定的地址范围,Cache允许绕过总线系统,通过指针直接且非常有效地访问内存(而不是路由TLM事务)。 TQ允许(本地)推迟与SystemC内核的同步,方法是在可配置TQ值的(全局)模拟时间之前运行。这是一种常见的优化技术,在每个执行指令之后,通过避免同步(即执行到SystemC内核4. 基于VP的自适应仿真:在快速和准确之间切换在本节中,我们将介绍基于VP的自适应模拟方法,该方法允许在运行时无缝切换ISS中的精度设置,以尽可能快地模拟(嵌入式)应用程序,并根据需要保持准确性。我们从4.1节中的核心架构概述开始。然后,我们介绍了基于解释器(第4.2节)和基于JIT(第4.3节)的执行设置,它们紧密集成,以实现非常轻量级的切换操作。最后,我们将在4.4节中讨论实现切换的不同替代方案及其权衡。4.1. 核心架构图1示出了具有最相关的组件和它们之间的关系的架构概述。 中心是ISS。 ISS基本上由三个部分组成:状态、解释器和JIT。 状态包括(RISC-V)ISA状态,即程序计数器(PC)和寄存器值,以及解释器和JIT相关的数据结构。 解释器一个接一个地获取、解码和执行指令。JIT能够通过将指令直接翻译成主机汇编指令来加速执行(与解释器一起,Fig. 1. 体系结构概述。它的工作原理如下:首先,将内存访问地址从通过使用内存管理单元(MMU)将虚拟地址转换为物理(v2p)地址。在没有MMU的系统中,或者如果MMU当前被禁用,则v2p是无操作,因为系统已经使用物理地址工作)。2然后将得到的物理地址与可用的IP地址范围进行比较,即(开始,结束)地址对的列表。如果匹配,则直接通过UART处理内存访问,从而绕过TLM总线。否则,存储器访问被转换为TLM事务,并通过总线路由到(SystemC)目标外围设备或存储器。ISS和存储器接口都可以更新内核时序模型。时序模型提供了一组接口函数,这些函数是为ISS中基于解释器和JIT的执行设置量身定制的。我们将在4.2节和4.3节分别提供更多信息。定时模型利用SystemC量子保持器在(可配置的)TQ之后与SystemC内核ISS中的JIT设置利用了JIT编译器(在我们的例子中,它将RISC-V指令转换为x86_x64汇编)。JIT编译器可以访问与基于解释器的设置共享的ISS状态。它生成x86_x64汇编指令,直接读取和写入共享状态,以确保状态在切换之间保持一致。出于优化的目的,JIT编译器使用JavaScript并管理轻量级v2p缓冲区,以在MMU存在的情况下加速加载和存储指令的执行。我们将在第5节中详细介绍JIT编译器。根据当前设置,主ISS模拟循环在每次迭代中执行基于解释器(第4.2节)或基于JIT(第4.3节)的执行步骤。在下文中,我们将详细介绍这两种设置以及如何实现切换(第4.4节)。4.2. 基于口译员的设置图图2示出了基于解释器的执行步骤。这涉及到获取和解码(第4行)以及执行(第10行)下一条指令。出于调试目的,可以选择打印解码后的指令(第6行)。在每次执行之后,ISS检查中断并处理它们(如果可用)(第12行)。指令提取或执行可能会导致陷阱(例如内存访问错误)。我们已经使用异常实现了陷阱,并在第13行捕获它们。根据RISC-V语义,陷阱或中断将执行(通过设置PC)转移到SW陷阱/中断并在此后重新使用它们我们提供更多信息-分别在第4.2节和第4.3节中介绍了基于解释器和基于JIT的内存接口(Fig. 1中心)由ISS用于指令提取以及加载和存储指令的处理2要实现v2p,MMU可能需要访问内存接口本身来加载(并可能存储)页表索引(PTE)。有关MMU的RISC-V规范的更多信息,请参阅[2](特别是第4章:V. Herdt等人Journal of Systems Architecture 116(2021)1021354图二. ISS解释器设置执行单步。处理程序(传输的原因通过RISC-V专用寄存器提供)。这将分别发生在14号线和12号线在指令执行之前和之后,相应地通知所附的定时接口(分别为第8行和第16行)。请注意, 定时接口可以访问ISS,因此可以访问ISA图三. ISS JIT设置执行单步。4.3.1. BB查找状态信息以及中间执行信息。这包括最后一次访问的内存地址,是否采取了最后一个分支,提取的指令字,解码的操作码,当前PC(用于提取)以及下一个PC(在解码期间计算),以及是否执行捕获或中断发生。使用执行前和执行后更新函数对于访问指令执行前后的状态(特别是寄存器值)非常重要。这些信息使得能够将CA定时模型附加到ISS。4.3. 基于JIT的设置图3显示了基于JIT的执行步骤。与解释器相比,JIT步骤在基本块(BB)上而不是单个指令上操作。BB本质上是以跳转或分支结束的线性指令序列。首先,在第3行中,将(虚拟)PC转换为物理PC(PPC)地址。在MMU被禁用或不可用的情况下,这是无操作(即PPC = PC)。3 请注意,基于解释器的设置还利用MMU来获得PPC。如果JIT BB已经可用于PPC,它将直接执行(第9行)。否则,BB将被收集、编译和存储以供后续参考(第11行)。在收集期间,使用现成的解释器函数来直接执行一个接一个收集的基本块指令。在每个JIT步骤之后,中断被检查和处理,类似于解释器循环。陷阱可以中断JIT执行(因此导致BB提前离开),并将在捕获的指令之后立即处理。请注意,第3行中MMU下面我们将详细介绍BB查找(第7行)、收集(第11行)和执行(第9行)功能,这些功能构成了基于JIT的执行的基础。3我们使用PPC而不是PC进行基本的块映射,因为v2p映射可能在运行时经常被软件改变,例如Linux就是这样做的。用于上下文切换,并且还取决于固有的模拟器状态。出于性能原因,我们为BB查找管理两个映射。一个固定大小(4096)的直接映射缓存(DMC),首先查询,然后在PPC不在DMC中时使用哈希映射作为备用。每个DMC中的条目是一对(PPCDMC,BB)。PPC的低位(12)用于索引到DMC中,然后将PPC与PPCDMC进行比较。如果它们匹配,则返回BB,否则使用PPC查询哈希映射。请注意,我们清除DMC和散列映射每当指令内存被修改。这对于支持应用软件的动态加载或重定位(例如,如Linux所做的)以及自修改代码是必要的。为此,RISC-V提供了FENCE_I fence指令,该指令必须放置在软件中,以确保修改 的指令存储器变得对处理器可见4.3.2. BB收集BB收集功能为PPC创建一个新的BB。它类似解释器执行步骤函数(图2),但有三个不同之处。首先,它不处理中断(因为它们将传输执行到不同的地方,因此离开基本块)。第二,它会一直持续到找到基本块的末尾。因此,解释器管理一个特殊的bb_end布尔变量,该变量在每次指令执行后都会更新。第三,在解码之后和执行之前,收集指令信息(PC、解码的操作码、提取的指令字)。在BB被收集(并沿着过程执行)之后,BB被传递到JIT编译器以产生JIT编译函数。我们在第5节中提供了有关编译步骤的更多信息。4.3.3. BB执行BB execute函数执行JIT编译的 功能 (Line15)。它将当前(虚拟)PC作为主机4,并返回4PC参数仅在具有虚拟内存的系统中才需要。原因是v2p映射在执行过程中可能会发生变化(例如在引导Linux时)。因此,在编译期间将PC嵌入BB函数不起作用(因为跳转/分支执行PC相对更新)。V. Herdt等人Journal of Systems Architecture 116(2021)1021355模拟的执行周期数,用于更新时序模型并与SystemC内核同步(第17行)。通过为每个指令分配固定数量的周期来计算仿真周期,即指令精确(IA)定时模型。请注意,BB函数的编译方式是直接操作和更新ISS状态,特别是寄存器和PC。因此,在函数返回后(第15行),ISS状态与解释器完全一致。因此,在每个JIT(图3)和解释器(图2)步骤之后,执行可以在基于JIT和基于解释器的设置之间直接和任意地交换。最后,BB可以通过将多个BB链接在一起(第19行)来进行优化。我们提供了关于JIT的更多细节,包括编译步骤和这个可选的链接优化,在第5节。4.4. 切换设置切换配置基本上提供初始启动设置以及应用程序特定部分的设置,例如函数。 或PC范围。这可以通过提供切换命令来实现,切换命令是成对的(切换器-PC,目标设置)。这意味着在运行时切换到ISS中的目标设置,此时PC等于Buller-PC。通常,切换可以以两种方式之一来实现:(1)通过将切换命令嵌入到SW应用中,或者(2)通过将切换命令传递/嵌入到ISS中。 这两种方法可以以不同的方式实现,并且具有一定的权衡。通常,将开关命令嵌入SW中可提供非常精确的控制以及高性能。但是,需要重新编译软件(这也意味着源代码必须可用)并修改软件(这意味着分析的软件二进制文件与实际软件二进制文件略有不同)。 另一方面,将它们传递到ISS更灵活,并且不需要修改SW应用程序。但是,它可能会导致额外的性能开销,并且可能并不总是适用(例如,当在Linux中执行应用程序时,可能不清楚应用程序将在哪个地址加载)。我们在下面讨论这两种方法的实现。4.4.1. 嵌入软件切换可以通过自定义指令来实现。这种方法特别适合RISC-V,因为RISC-V是以非常可扩展的方式设计的,因此为自定义指令提供了指定的操作码空间。目标设置可以被编码为指令中操作码旁边或者,也可以使用自定义系统调用(syscall)来实现切换。在RISC-V中,系统调用由ECALL指令触发,参数(通常)传递到寄存器a7(系统调用编号)以及a0到a3(系统调用的参数)。然后,在ISS中拦截syscall(指令)并进行相应处理。使用syscall更容易实现(它不需要修改解码器并为新指令找到未使用的操作码)。但是,必须小心选择未使用的系统调用号(根据应用程序可能不同4.4.2. 通过/嵌入ISS可以在ISS中执行的同时在运行时检查触发PC。在解释器设置中,这基本上是没有问题的,因为额外的性能开销对整体解释器性能没有太大影响(因为解释器已经执行了非常详细和准确的执行)。然而,(相对)性能开销在JIT设置中更明显(因为JIT比解释器快得多此外,指令之间的准确切换需要在每次指令执行之后执行检查为了避免这个问题,应该只在JIT编译期间执行检查(即,当第一次执行指令时在PC匹配触发PC的情况下,则通过将自定义切换指令(或系统调用指令序列)嵌入到BB中来结束BB。因此,该BB的后续执行将通过 这是一个快速而准确的定制指令或者,为了获得更大的灵活性,可以利用调试器接口在调试过程的同时执行交互式切换(即,一旦命中断点,执行控制就转移到调试器,然后调试器可以相应地指示ISS)。在本文中,我们使用嵌入方法(变体1)通过使用自定义系统调用进行切换。在下文中,我们将介绍有关JIT编译器后端的更多细节。5. 用于基于VP的模拟的本节介绍我们的JIT编译器后端以及与基于VP的模拟的集成。 JIT编译器后端由ISS的JIT设置访问,以编译和优化BB。首先,我们介绍如何处理BB(第5.1节)。然后,我们描述了JIT代码如何与解释器交互(第5.2节),并提出了两个优化(第5.3节和5.4节)。5.1. 编译基本块BB在第一次执行时被收集并编译成(本机x86_x64主机)函数。编译后的函数由三部分组成:序言、主体和结尾。序言部分描述了BB的执行,主体一个接一个地实现RISC-V指令,并且Epilog结束执行并向函数的调用者提供返回值。该函数被编译为直接对ISS解释器状态(寄存器值和PC)进行操作。例如执行RISC-V加法ADD x1,x2,x3,RISC-V源寄存器(x2,x3)的值被加载到x86_x64寄存器中,然后在x86_x64寄存器上执行加法,最后将结果存储回RISC-V目的寄存器(x1)。这确保了JIT和解释器设置之间的执行状态始终一致,并且JIT执行可以在每个指令之后轻松中断(在陷阱或强制与SystemC内核同步的情况下)。例1. 图图4显示了一个示例来说明总体思路:RISC-V汇编程序(左上),该程序的BB集(右上)以及转换为x86_x64汇编的两个BB。符号BB(N)表示从地址N开始的BB。每个RISC-V指令的长度为32位,程序从地址0开始RISC-V程序中每条指令的地址显示在相应指令的左侧。该程序通过初始化RISC-V寄存器x1至x3(LI =立即加载,第1-3行)开始然后计算x1到x2(包括x1和x2)的和,并将结果存储在x3中(第4一旦x1变得大于x2(BGT),则退出循环=Branch Greater)。请注意,HALT表示本示例中RISC-V指令每个转换后的BB首先将x86_x64rbx寄存器初始化为指向ISS状态区域,该区域仅作为具体(指针)值提供,即BB(0)中的第3行。 push(在序言中)和pop(在后记中)确保rbx的原始值被保留(我们在这里使用被调用方保存的寄存器,以确保在以下情况下保留rbx JIT代码调用一个解释器函数,见5.2节)。在BB主体中,RISC-V指令被一个接一个地翻译。与RISC-V相比,x86_x64使用两种操作数形式,将第一个参数用作源寄存器和目标寄存器。此外,大多数具有两个操作数的x86_x64指令可以接受一个存储器操作数(而不是寄存器)。@addr构造构建这样的内存操作数,即x86_x64指针表达式,以访问RISC-V寄存器/PC的内存。例如,假设ISS状态是一个简单的structState {uint32_t[32]; uint32_t PC;},则@addr(x2)V. Herdt等人Journal of Systems Architecture 116(2021)1021356见图4。 示例RISC-V程序和JIT编译的BB。等于rbx + 2*4,@addr(PC)等于rbx + 32*4。 中间结果存储在(调用者保存的)寄存器中,在本例中是eax/rax。 根据RISC-V程序地址实现分支和跳转以更新PC5最后,返回值(根据x86_x64调用约定,通过rax我们简单地为每条指令设置一个周期,尽管这是每条指令可配置的。65.2. 解释器回退许多指令可以在JIT模式下完全执行,这是非常有效的。然而,有些指令要么太复杂,要么具有非常特殊的语义,因此我们提供了一个简单的方法来回退对特定指令的基于解释器的执行。特别地,我们利用解释器来执行加载/存储指令(因为它们可以指向外围设备,尽管在5.3节中我们讨论了优化为了放宽该要求)、浮点指令、特殊寄存器访问指令、系统调用相关指令和(虚拟)存储器围栏。出于这个原因,我们在ISS中提供了一个(通用)包装器函数(使用解释器设置执行单个指令)。这个函数可以从JIT(生成的)代码中调用。这需要根据主机系统的调用约定准备调用堆栈并将参数存储在(x86_x64主机)寄存器中。我们传递三个参数:(1)指令PC,(2)解码的操作码,以及(3)获取的指令字。 所有这些信息都可以在收集的BB中找到。如果在执行过程中发生了陷阱,包装器函数被设置为返回零(在这种情况下,包装器函数也将在返回之前设置到陷阱处理程序的跳转)。根据返回值,JIT代码要么继续(没有陷阱),要么跳转到BB的退出标签(发生陷阱)。5在虚拟地址的情况下,PC更新需要考虑当前PC值(见图1)。 第15行)。6 一般来说,我们使用x86_x64寄存器作为周期计数器(在每个指令),以确保循环计数是准确的,即使BB由于陷阱而提前离开(对于可能导致陷阱的BB5.3. 加载/存储优化为了加速加载和存储指令的执行,我们生成 JIT代码,允许在内存访问落入范围内时绕过内存接口(即访问内存,而不是外围设备)。然而,在BB编译期间,不可能(在一般情况下)决定访问是否将在缓冲区范围内(因为除了立即偏移量之外,内存地址还取决于寄存器值)。因此,我们将检查放在JIT代码中。 如果JavaScript检查成功,JIT代码将处理内存访问(基于JavaScript指针),否则解释器回退函数 从JIT代码中调用(见5.2节)。我们在具有MMU的系统中对虚拟到物理(v2p)地址转换进行了额外的优化。v2p的问题是,它需要对每次内存访问都执行,并且需要调用JIT代码中的外部(ISS)函数,以便访问MMU。相反,我们管理专门定制的简化v2p缓冲区 分别用于加载和存储指令。与MMU相比,它区分不同的访问类型(读取,加载和存储)以及依赖于固有的RISC-V ISA状态(例如特权级别),我们的缓冲区更轻量级。总共需要10条x86_x64汇编指令来检查虚拟地址是否在缓冲区中并返回相应的物理地址。请注意,v2p在页面上工作(而不是单个地址),因此单个缓冲区条目覆盖多个地址。如果虚拟地址(页面)不在缓冲区,从JIT代码调用正常的解释器回退函数(参见5.2节),并将地址(页面)添加到缓冲区中。最后,当SW中的v2 p映射改变(由RISC-V SFENCE_VMA围栏指令发信号通知)或相关ISA状态被修改(例如,特权级别改变)。5.4. 链接优化将多个BB链接在一起是一种常见的优化技术在基于JIT的编译器中,它允许通过在JIT代码中停留更长时间来加速执行性能(非常显着)。 我们结合了基于跟踪和传统的链接优化技术。此外,我们确保与SystemC内核进行定期同步。一旦BB的执行计数达到某个阈值(我们使用1000次执行),我们就开始链接优化过程。首先,尝试基于跟踪的优化。它的工作原理是一个接一个地收集所有已执行的BB,直到找到一个BB循环(称为跟踪)。例如,来自图4的BB(16)和BB(12)形成迹线,其中BB(16)是起始BB。为跟踪生成单个序言和结尾。的主体只是一个接一个地实现每个BB的RISC-V指令。在主体的末尾,放置一个返回到开头的跳转。 为了留下痕迹,警卫被安排在分支机构的指令处。一个保护程序检查分支是否采用跟踪方向,否则它通过执行到epilog的跳转来离开跟踪。另外,我们安排一个警卫一旦循环计数器(在每个指令之后递增)达到某个阈值(JIT量),就在主体的开始处离开跟踪。这使得与SystemC内核的定期同步成为可能。可能无法收集有效的跟踪。 当没有找到循环(在一定数量的执行BB之后),中断/陷阱拦截跟踪收集,或者到达已经链接优化的BB(它不再是简单的BB)时,就会发生这种情况。在这种情况下,我们执行传统的链路优化。它的工作原理是从开始BB收集分支和(直接)跳转指令可到达的BB。然后,将收集的BB集编译为单个本机函数,将分支 并相应地在编译的BB之间跳转指令。我们在每次向后跳转时放置退出保护(类似于跟踪编译)以确保与SystemC内核的定期同步。这两个链接优化都在原地工作,即新编译的函数覆盖现有的BB函数。V. Herdt等人Journal of Systems Architecture 116(2021)10213576. 实验我们已经使用开源的基于SystemC的RISC-V VP [13,48]作为案例研究实现了我们的自适应仿真方法。 我们使用asmjit[49]库作为JIT编译器的后端。 首先,我们在第6.1节中介绍了性能评估。 它显示了基于SystemC的VP中不同ISS执行设置的性能影响,并将其与其他RISC-V模拟器进行了性能比较。然后(第6.2节),我们讨论了一个基于Linux的案例研究,展示了我们的方法的适用性和好处。所有实验都是在具有Inteli5- 7200 U处理器的Linux系统上进行的。6.1. 绩效评价6.1.1. 模拟器设置我们在VP中考虑了六种不同的ISS设置用于该评估:基础、+TQ、+IA、+JBB、+JL。前四个设置是基于解释器的,后两个是基于JIT的。该设置提供vide时序精度和仿真性能之间的权衡。Base提供最精确的模拟设置。它既不使用TQ(即,因此在每个执行的指令之后,ISS与SystemC内核进行同步)也不使用同步(即,因此每个加载/存储操作和指令提取被打包到TLM事务中并通过TLM总线路由)优化。此外,我们根据[50]将示例CA核心时序模型附加到ISS(允许考虑流水线,分支预测和缓存时序效应)。 + Bit扩展了Base,并对指令提取和主存访问进行了Bit优化。+TQ通过TQ优化扩展了+TQ,仅每10,000个周期与SystemC内核同步。+IA修改+TQ以用轻量级指令精确(IA)定时模型(即,每个指令使用固定数量的周期)来替换CA定时模型。+JBB通过基于JIT的ISS扩展了+IA,该ISS可以转换单个基本块。+JL扩展了+JBB的基本块链接优化。 我们对+JL使用10,000个周期的JIT量来匹配TQ。 所有设置均使用VP的通用TLM-2.0总线访问(基于SystemC的)外设。在本实验评估中,我们重点关注不同精度设置对性能的影响,并将精度结果的评估留给未来的工作。请注意,基于解释器的ISS设置(Base,+TQ,+IA)不使用JIT,因此它们也可以用作比较,以查看在SystemC TLM模拟中使用JIT的收益。特别是,通过比较+IA和+JL,它们分别是最快的基于解释器和基于JIT的设置。除了ISS设置的比较之外,我们还提供了四个RISC-V模拟器的性能比较(设计时考虑了不同的用例),以便更好地将VP性能结果联系起来:QEMU [8](超快速模拟性能),SPIKE [7](高速RISC-V参考模拟器),gem 5 [12](架构探索和详细模拟)和SAIL [19](正式分析技术的基础)。对于SAIL,我们使用生成的C后端。6.1.2. 基准我们使用三个基准集进行评估:Embench,Zephyr和基于Linux的基准。Embench[51]是一个免费提供的标准基准测试套件,专门针对嵌入式设备。它是一个真实而不是合成程序(如Dhapeone或Coremark)的集合,以确保考虑更现实的工作负载它包含例如执行错误检查、散列、加密和解密、排序、矩阵乘法和求逆、JPEG和QR码以及正则表达式和状态机操作的基准。基准测试具有不同程度的计算、分支和内存访问复杂性[52]。基准测试主体的执行迭代次数是可配置的,具体次数取决于CPU频率。迭代计数在不同的基准测试中有所不同,以确保运行时复杂度跨基准套件。我们已将CPU频率设置为常数到1000 MHz。Zephyr是一个主要针对(资源受限)嵌入式系统设计的操作系统。我们考虑四个基准测试,它们广泛使用线程进行计算,使用消息队列进行通信(在线程之间发送数据):螺纹.第一个线程使用TinyCrypt库中的aes128算法加密一个100 MB的数据集transmit-loop在三个线程之间的循环中传输消息。它可以执行100,000个传输环路。UART转储在一个线程上生成伪随机数据,然后将该数据发送到第二线程上的UART设备。qsort-filter类似于uart-dump,但在两者之间添加了一个额外的线程,以使用qsort算法对生成的数据进行排序。与Embench相比,Zephyr基准测试还访问外围设备(Embench是一个纯CPU基准测试集)来评估整个系统的性能特征。此外,Zephyr利用线程,结合抢占式调度器,这需要模拟几个上下文切换。Linux进一步扩展了基准测试的复杂性。它是一个成熟的操作系统,需要RISC-V ISA的广泛支持,并利用高级执行功能,如特权级别和虚拟内存。我
下载后可阅读完整内容,剩余1页未读,立即下载
cpongm
- 粉丝: 5
- 资源: 2万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 黑板风格计算机毕业答辩PPT模板下载
- CodeSandbox实现ListView快速创建指南
- Node.js脚本实现WXR文件到Postgres数据库帖子导入
- 清新简约创意三角毕业论文答辩PPT模板
- DISCORD-JS-CRUD:提升 Discord 机器人开发体验
- Node.js v4.3.2版本Linux ARM64平台运行时环境发布
- SQLight:C++11编写的轻量级MySQL客户端
- 计算机专业毕业论文答辩PPT模板
- Wireshark网络抓包工具的使用与数据包解析
- Wild Match Map: JavaScript中实现通配符映射与事件绑定
- 毕业答辩利器:蝶恋花毕业设计PPT模板
- Node.js深度解析:高性能Web服务器与实时应用构建
- 掌握深度图技术:游戏开发中的绚丽应用案例
- Dart语言的HTTP扩展包功能详解
- MoonMaker: 投资组合加固神器,助力$GME投资者登月
- 计算机毕业设计答辩PPT模板下载
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功