计算机系统架构模拟的定量评估与方法解析
1. 概述
随着越来越多的设备和功能被集成,现代计算机系统正变得日益复杂。在系统的整个设计周期中,模拟是计算机架构研究人员评估新想法和探索设计空间的关键工具。与硬件原型设计和分析建模相比,模拟在准确性、成本、灵活性和复杂性之间取得了更好的平衡。
随着最先进的微处理器设计复杂性的不断增加和制造成本的飙升,计算机架构模拟变得至关重要。模拟在计算机架构研究和设计中无处不在,并在很大程度上影响着这些活动的生产力。生产力在两个层面受到影响:一是开发模拟器所花费的时间和精力,二是使用代表性基准运行模拟所消耗的时间。
微处理器芯片集成密度的急剧增长为计算机架构师提供了丰富的片上资源,使他们能够通过更复杂的架构设计来增强计算能力。此外,功率和可靠性已成为关键的设计约束。构建一个允许设计师在单一统一框架中考虑性能、功率和可靠性的模拟基础设施,会导致模拟器开发成本显著增加和延迟。复杂基础设施的另一个直接后果是模拟本身变慢,增加了每个设计状态探索的周转时间。
随着计算机架构进入芯片多处理器(CMP)时代,模拟速度变慢的问题变得尤为严重。目前在单线程中模拟核心数量不断增加的CMP的方法是不可扩展的,无法长期持续。如果像过去大多数单处理器系统那样以顺序方式模拟CMP,模拟时间将不可避免地以极快的速度增加。认识到问题的重要性,人们已经构思了几种方法来加速模拟并更有效地建模未来系统,以下将详细介绍各种模拟方法以及加速模拟的途径。
2. 模拟器的分类
计算机架构模拟主要涉及模拟器和基准测试两个方面。模拟器对目标机器的关键特征或行为进行建模,根据不同的设计目标和约束,目标处理器可以在不同的细节和精度级别上进行模拟。基准测试是运行在目标处理器上的一组程序,用于评估目标机器的一个或多个组件。设计和使用计算机架构模拟器需要在高模拟精度、高模拟速度和低开发工作量之间进行权衡,这些目标往往相互冲突。计算机架构师必须对目标进行优先级排序,以选择特定的模拟工具。模拟器可以根据其模拟的内容和模拟的详细程度进行分类,具体如下:
2.1 用户级与全系统模拟器
- 用户级模拟器 :处理器是计算机架构研究和设计的主要目标,用户级模拟器专注于模拟处理器的微架构,忽略了一些系统组件,如协处理器和I/O设备。基准测试在模拟器上执行,该模拟器仅模拟用户代码。当基准测试需要访问未模拟的系统资源(如I/O设备)时,仅模拟该资源分配的架构影响,而忽略微架构影响。例如,如果系统调用更新了架构寄存器,寄存器更新会在模拟中反映出来,但系统调用内发生的一切都被视为黑盒,无法测量系统调用内的微架构影响。尽管用户级模拟器忽略了一些重要的系统影响,但它们仍然能够运行现实的应用程序,近似完整的工作环境,并忠实地保持工作负载的真实性。用户级模拟器通过仅关注处理器设计并有意省略计算机系统的一些子系统来简化建模工作,前提是这种省略不会损害模拟的可信度。在大多数情况下,操作系统(OS)活动被省略,这有时会导致一些不可接受的错误。然而,它们相对简单、开发工作量有限且易于使用,在计算机架构社区中非常有吸引力。常见的用户级模拟器有SimpleScalar、Asim、MINT、RSIM、Zesto和Shade等,用于评估微架构的性能指标,如IPC、分支预测准确性或缓存命中率。此外,还有一些用户级的功率和能量估计工具,如Wattch是SimpleScalar的扩展,用于在架构级别评估功率。
- 全系统模拟器 :全系统模拟器对包括CPU、I/O、磁盘和网络在内的整个计算机系统进行建模,能够启动和运行未修改的操作系统,从而捕捉工作负载与整个系统之间的交互。随着驱动高端计算的应用从科学/工程转向信息处理应用(如数据库、决策支持和网络搜索引擎),全系统模拟器变得越来越重要。这些商业应用有更多的系统活动,在模拟中忽略这些活动会导致观察指标出现显著的模拟偏差。例如,事务处理工作负载在OS模式下花费20 - 30%的时间,并且应用在OS模式下的行为与用户级模式下的行为有很大不同。因此,对于商业应用,必须忠实地模拟所有系统组件。常见的全系统模拟器有SimOS和Simics等,SimOS在指令集级别对应用程序与OS的交互进行功能建模,适用于系统软件开发的调试;Simics是工业级的全系统模拟器,能够启动未修改的OS,支持多种ISA。
| 模拟器类型 | 模拟范围 | 优点 | 缺点 | 常见工具 |
|---|---|---|---|---|
| 用户级模拟器 | 处理器微架构,忽略部分系统组件 | 简单、开发工作量小、易使用,能运行现实应用 | 忽略重要系统影响,可能导致错误 | SimpleScalar、Asim、MINT等 |
| 全系统模拟器 | 整个计算机系统 | 能捕捉系统交互,适用于商业应用 | 开发复杂,模拟速度慢 | SimOS、Simics等 |
2.2 功能与周期精确模拟器
- 功能模拟器 :功能模拟器仅模拟处理器每条指令的功能,不涉及任何微架构细节,通常作为构建更复杂模拟器的起点。在对目标处理器的详细微架构进行建模之前,先在这类模拟器中正确模拟其指令集架构(ISA),这种方法将指令集的逻辑/功能建模与目标处理器的微架构建模分离。功能模拟器速度快,但对目标系统的洞察有限,只能提供简单的统计信息,如指令计数或静态/动态指令混合。
- 周期精确模拟器 :周期精确模拟器捕捉所有微架构块的细节,不仅模拟各种微架构块的功能,还通常跟踪时序。由于跟踪时序,这些模拟器能够提供性能结果,对于评估不同的设计选项很有价值。为了使这些模拟器正确运行,设计师必须详细编码微架构设计,并将时序信息作为输入提供给模拟器。大多数微架构块在模拟器中是参数化的,例如,模拟器中缓存组件的大小、关联性和行大小可以配置为用户定义的值,以便在不重新编译模拟器代码的情况下探索各种缓存配置的设计空间。周期精确模拟器能提供更多关于目标机器性能瓶颈的洞察,但开发和运行速度较慢。
以SimpleScalar工具集为例,它包含多个不同精度的用户级模拟器。sim - fast是最快、最不详细的模拟器,仅模拟指令执行,不涉及微架构细节,只跟踪目标机器的架构状态;sim - outorder是最详细的模拟器,能够以周期级精度模拟多级缓存层次结构、分支预测和乱序发行与执行。此外,还有sim - cache和sim - branch等模拟器,分别用于模拟缓存和分支预测,通过这种粗粒度的模块化模拟器,设计师可以快速探索和修剪特定微架构块的设计空间,然后再使用更详细的sim - outorder进行周期精确模拟。
graph LR
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
A([开始]):::startend --> B(功能模拟器):::process
A --> C(周期精确模拟器):::process
B --> D(简单统计信息):::process
C --> E(复杂性能指标):::process
D --> F(指令计数等):::process
E --> G(CPI、命中率等):::process
F --> H(设计初步探索):::process
G --> I(详细设计评估):::process
H --> J([结束]):::startend
I --> J
2.3 跟踪驱动、执行驱动和直接执行模拟器
- 跟踪驱动模拟 :在跟踪驱动模拟中,首先在与ISA兼容的处理器(或其模拟器)上执行基准测试,但不一定是目标处理器。在基准测试执行期间,每条指令都会被记录到跟踪文件中,记录可以由真实机器上的硬件监视器或模拟器(此时模拟器也称为跟踪生成器)完成。收集的跟踪可以是整个基准测试执行的跟踪,或者更常见的是设计师确定的基准测试的感兴趣部分。在开始跟踪收集之前,会记录处理器的整个架构状态。在跟踪收集阶段,一些跟踪收集基础设施(如用户级软件跟踪生成器)会跟踪系统调用,此时跟踪生成器可能只记录系统调用执行前后的架构状态。同样,当在跟踪过程中遇到中断事件时,跟踪生成器会记录中断前后的架构状态。每个跟踪文件是跟踪记录的集合,可选地前面带有架构状态。在多处理器系统或CMP的执行跟踪中,不同线程的跟踪记录会根据它们在跟踪生成器执行中的出现顺序交织在一个跟踪文件中。收集到跟踪后,将其作为输入提供给周期精确模拟器,该模拟器使用详细的微架构模型模拟跟踪中的每条指令。跟踪驱动模拟的优点是跟踪只需收集一次,可用于模拟各种微架构配置,并且可以指导跟踪生成器在跟踪收集期间收集架构信息以简化周期精确模拟器。此外,跟踪文件是机器组件模拟器的固定输入,评估架构特征时不受其他架构部分行为的影响,这在多处理器模拟中尤为重要。然而,其缺点是周期精确模拟器无法准确量化推测的影响,并且在模拟大型工作负载时,跟踪文件大小是一个严重问题。
- 执行驱动模拟 :执行驱动模拟器不依赖于跟踪文件,而是将基准测试作为输入。模拟器解析基准测试可执行文件以加载初始架构状态,然后模拟基准测试在目标机器上的执行。该模拟器必须忠实地再现目标微架构的时序以及架构的功能方面,例如,必须知道如何处理ISA中每条指令的时序和功能,即使这些指令在基准测试执行期间只出现一次。由于将时序和功能结合在一个模拟器中,执行驱动模拟器的开发复杂,但准确性、灵活性和真实性优于跟踪驱动模拟器。
- 直接执行模拟 :直接执行模拟器在准确性和速度之间取得平衡。跟踪驱动和执行驱动模拟器都会在主机上模拟目标架构的每条指令,这会显著减慢模拟速度。直接执行模拟器通过在主机硬件上直接执行基准测试应用程序中的一些指令来牺牲一定的准确性以换取速度。当指令在主机硬件上直接执行时,模拟器不提供任何时序数据。设计师需要选择目标硬件的哪些组件进行详细建模,例如,如果只对数据缓存性能建模,除加载/存储指令外的所有指令都在主机硬件上直接执行。每当在基准测试中遇到加载/存储指令时,就会调用内存层次结构模拟器来模拟内存层次结构的性能。目标ISA必须与主机ISA相同,以便为目标架构编译的基准测试应用程序可以直接在主机硬件上运行。在直接执行模拟中,部分基准测试代码原生运行,部分代码在模拟环境中运行。为了实现这种复杂的交互,需要在源代码或目标代码级别对基准测试代码进行插桩。设计师提供在基准测试执行期间发生感兴趣事件时需要执行的模拟模块,编译器分析基准测试代码以确定代码中发生感兴趣事件的所有位置。例如,为了评估数据缓存性能,编译器会识别所有加载/存储指令,并在每个加载/存储指令之前插入对设计师提供的模拟模块的函数调用。模拟模块可以接收加载/存储指令的有效地址、程序计数器和其他相关数据作为输入。当插桩后的二进制文件在主机硬件上执行时,基准测试在执行加载/存储指令时会调用模拟模块函数。插桩可以在源代码级别进行,如果基准测试的源代码不可用,也可以使用二进制重写工具对基准测试二进制文件进行插桩,如ATOM和PIN等工具。
以下是ATOM工具对二进制文件进行插桩的示例代码:
Instrument (int argc, char ** argv , Obj *obj)
{
Proc *p, Block *b, Inst *inst;
for (p = GetFirstObjProc (obj); p != NULL; p = GetNextProc (p)) {
for (b = GetFirstBlock (p); b != NULL; b = GetNextBlkc(b)) {
for (inst = GetFirstInst (b); inst != NULL; inst = GetNextInst(inst)) {
if ((IsInstType (inst, InstTypeLoad) || (IsInstType (inst, InstTypeStore))) {
AddCallInst (inst, InstBefore , "SimulateCache", EffAddrValue);
}
}
}
}
}
在这个代码中,ATOM工具接收基准测试二进制文件作为输入,通过嵌套的循环遍历二进制文件中的每个指令。当遇到加载或存储指令时,会在该指令之前插入对“SimulateCache”函数的调用,该函数接收内存引用的有效地址作为参数。这样,当插桩后的二进制文件在主机硬件上执行时,就会在执行加载/存储指令时调用缓存模拟函数,实现直接执行模拟。
3. 模拟器集成方法
在构建模拟器时,有两种突出的集成方法,分别是时序优先和功能优先集成。这两种方法各有优劣,以下详细介绍。
-
时序优先集成
:这种方法先着重处理模拟器中的时序问题。在模拟过程中,优先确保各个组件的时序关系正确,例如在处理指令执行时,会先精确安排指令的执行时间,再考虑指令的功能实现。这样做的好处是能够更准确地模拟系统的性能表现,对于对时序要求较高的系统模拟较为适用。但缺点是开发难度较大,因为需要提前对系统的时序有深入的了解和精确的建模。
-
功能优先集成
:功能优先集成则是先实现模拟器中各个组件的基本功能。在模拟开始时,重点关注指令是否能正确执行其功能,而对时序的处理相对后置。这种方法的优点是开发相对简单,能够快速搭建起一个具有基本功能的模拟器框架,便于进行初步的功能验证。然而,由于对时序的处理不够及时,可能在后续的性能评估中需要进行大量的调整和优化。
| 集成方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 时序优先集成 | 准确模拟系统性能 | 开发难度大 | 对时序要求高的系统模拟 |
| 功能优先集成 | 开发简单,快速搭建框架 | 后续性能评估需调整 | 初步功能验证 |
4. 多处理器模拟方法
随着芯片多处理器(CMP)的普及,多处理器模拟变得越来越重要。主要有单线程和多线程两种模拟方法。
-
单线程模拟器
:在单线程模拟器中,只有一个主机线程运行所有的模拟任务。这种方法简单直接,易于实现,但随着CMP核心数量的增加,模拟速度会变得非常慢,因为所有任务都要按顺序依次执行,无法利用多核处理器的并行计算能力。
-
多线程模拟器
:多线程模拟器本身是多线程的,每个模拟器线程模拟目标核心的一个子集,甚至是模拟活动的一个子集。通过并行模拟,可以显著提高模拟速度。但多线程模拟也带来了同步问题,不同线程之间需要进行有效的同步,以确保模拟结果的准确性。为了解决同步问题,有多种同步方法可供选择,例如锁机制、信号量机制等,但这些方法往往会在一定程度上牺牲模拟的准确性来换取速度。
graph LR
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
A([开始]):::startend --> B(单线程模拟器):::process
A --> C(多线程模拟器):::process
B --> D(顺序执行任务):::process
C --> E(并行执行任务):::process
E --> F(同步问题):::process
F --> G(选择同步方法):::process
D --> H(模拟完成):::process
G --> H
H --> I([结束]):::startend
5. 功率和热模拟
在计算机系统设计中,功率和热是重要的考虑因素。随着处理器性能的不断提升,功率消耗和散热问题日益突出。因此,对功率和热进行准确的模拟变得至关重要。
-
功率模拟
:功率模拟主要是评估计算机系统在运行过程中的功率消耗。可以通过建立功率模型来实现,例如在每个周期中,对每个活动单元的功率模型进行调用,计算并记录所消耗的功率。常见的功率模拟工具如Wattch、SimplePower和TEMPEST等,这些工具可以在架构级别对功率进行评估。
-
热模拟
:热模拟则是预测计算机系统在运行过程中的温度分布。它需要考虑芯片的散热特性、功率消耗以及环境温度等因素。准确的热模拟可以帮助设计师优化散热方案,确保系统在安全的温度范围内运行。
6. 加速模拟的采样技术
由于架构模拟速度较慢,在当前主机机器上运行最新的基准测试套件到完成变得越来越困难。为了解决这个问题,采样技术应运而生。采样技术的核心思想是选择基准测试执行中最具代表性的部分进行模拟,而不是对整个基准测试进行模拟。
-
Simpoint方法
:Simpoint方法通过分析程序的执行轨迹,找出程序执行中的关键阶段,并选择这些阶段的样本进行模拟。具体步骤如下:
1. 收集程序的执行轨迹,记录程序在运行过程中的各种状态信息。
2. 对执行轨迹进行聚类分析,将相似的执行阶段归为一类。
3. 从每个聚类中选择一个代表性的样本作为模拟的输入。
-
系统随机采样方法
:系统随机采样方法则是按照一定的规则随机选择基准测试执行中的样本。例如,可以按照固定的时间间隔或指令数量间隔进行采样。这种方法简单易行,但可能无法保证采样的样本具有足够的代表性。
7. 工作负载特征化
工作负载特征化是为了理解架构和工作负载之间的相互作用。通过对工作负载的特征进行分析,可以帮助设计师更好地优化架构设计,以满足不同工作负载的需求。
-
特征分析方法
:可以从多个方面对工作负载进行特征分析,例如指令执行频率、内存访问模式、缓存命中率等。通过收集和分析这些特征数据,可以了解工作负载的行为模式。
-
应用场景
:工作负载特征化的结果可以应用于多个方面,例如在架构设计阶段,可以根据工作负载的特征选择合适的架构参数;在系统优化阶段,可以根据工作负载的特征调整系统的运行策略,以提高系统的性能和效率。
综上所述,计算机系统架构模拟是一个复杂而重要的领域,涉及多种模拟方法、集成技术以及加速策略。通过合理选择和应用这些方法和技术,可以更高效地评估架构解决方案,为计算机系统的设计和优化提供有力支持。在实际应用中,需要根据具体的需求和场景,综合考虑各种因素,选择最合适的模拟方法和工具,以达到最佳的模拟效果。
超级会员免费看
1万+

被折叠的 条评论
为什么被折叠?



