下面按"参数都在哪 → V2 逐块讲 → V3 逐块讲 → 逐项对比 → 怎么理解"来梳理。先说结论:XS-GEM5(XG-Gem5)里 V2/V3 的"运行脚本"本身几乎是空壳,真正决定微架构的是它调用的那个 Python 配置脚本。
一、参数到底藏在哪几层
| 层次 | 文件 | 作用 |
|---|---|---|
| 运行脚本 | util/xs_scripts/kmh_6wide.sh → configs/example/kmhv2.py --generic-rv-cpt=$1 |
只做环境检查 + 传切片路径,本身没有微架构参数 |
| 运行脚本 | util/xs_scripts/kmh_v3_btb.sh → configs/example/kmhv3.py --generic-rv-cpt=$1 |
同上;kmh_v3_ideal.sh 走 idealkmhv3.py |
| 配置脚本 | configs/example/kmhv2.py |
只覆盖 5 个 args,其余走 CPU 默认值 |
| 配置脚本 | configs/example/kmhv3.py |
用 setKmhV3Params() 显式覆盖几十项 |
| 参数基准面 | src/cpu/o3/BaseO3CPU.py |
O3 核所有 Param 的默认值,这套默认值就是昆明湖 V2 的校准点 |
| 调度器 | configs/common/FUScheduler.py |
KunminghuScheduler(V2)vs KMHV3Scheduler(V3) |
| 命令行默认 | configs/common/Options.py |
cache 容量/相联度、预取器类型、时钟、预取开关等 |
所以 V2 = BaseO3CPU 默认值 + KunminghuScheduler + kmhv2.py 的 5 个 args ;V3 = 在 V2 基准上再叠加 setKmhV3Params() 的显式覆盖。理解这一点,参数就不再是两堆孤立的数字。
二、昆明湖 V2 的参数(kmhv2.py)
kmhv2.py 的 __m5_main__ 只做了这些:
args.bp_type = 'DecoupledBPUWithBTB' # 解耦前端 BPU
args.l2_wrapper_hwp_type= "L2CompositeWithWorkerPrefetcher" # 与 Options 默认一致
args.kmh_align = True # 打开"对齐昆明湖"开关
args.cpu_clock = '2.4GHz' # 仅 xiangshan_ecore 时生效
test_mem_mode = 'timing'
kmh_align=True 是 V2 的灵魂开关,它联动改变访存侧行为:dcache.pipe_latency = 3、L2.do_fast_writeline = False、cpu.store_prefetch_train = False(即不再训练 store 预取)。
核心微架构参数(全部来自 BaseO3CPU.py 默认 + KunminghuScheduler):
| 模块 | 参数 | V2 取值 | 含义 |
|---|---|---|---|
| 取指 | fetchWidth / fetchQueueSize |
16 / 48 | 取指块宽度与取指队列 |
| 取指 | iewToFetchDelay / commitToFetchDelay |
1 / 3 | 后端重定向回传延迟 |
| 译码 | decodeWidth |
6 | 6 宽译码(这也是脚本叫 kmh_6wide 的原因) |
| 重命名 | renameWidth / phyregReleaseWidth |
6 / 6 | 6 宽重命名 / 释放 |
| 寄存器 | numPhysIntRegs / numPhysFloatRegs |
224 / 192 | 物理寄存器规模 |
| ROB | numROBEntries |
160 | 重定序缓冲 |
| ROB | RobCompressPolicy / CROB_instPerGroup |
'kmhv2' / 6 | V2 启用 ROB 压缩,每组最多 6 条 |
| ROB | commitWidth / squashWidth / RobWalkPolicy |
8 / 8 / 'Replay' | 提交、回滚宽度与回滚策略 |
| 分派 | enableDispatchStage / numDQEntries / dispWidth |
False / 32,16,16 / 8,6,6 | 分派级建模(默认关,容量仍按 V2 规模) |
| 调度器 | scheduler |
KunminghuScheduler | 4×intIQ(24项) + 7×memIQ(16项) + 3×fpIQ(18项),无向量 IQ |
| 调度器 | specWakeupNetwork |
2 条通道 | int+mem 互唤醒、fp 内部唤醒(fp 不参与 int 唤醒) |
| LSQ | LQEntries / SQEntries |
72 / 56 | .load / store 队列 |
| LSQ | RARQEntries / RAWQEntries |
72 / 32 | 访存违例检查队列 |
| LSQ | LoadCompletionWidth / StoreCompletionWidth |
8 / 4 | 每周期完成数 |
| Store buffer | SbufferEntries / SbufferEvictThreshold / sbufferBankWriteAccurately |
16 / 7 / False | sbuffer 规模与 bank 冲突建模(V2 不精确建模) |
| LSU | StoreWbStage / EnableLdMissReplay / EnablePipeNukeCheck / BankConflictCheck |
4 / True / True / True | store 在 S4 写回,load miss 重发、nuke 检查、bank 冲突检查全开 |
| 缓存 | L1I / L1D | 64kB(默认 4 路) | 由 Options.py 默认给出 |
| 缓存 | L2 / L3 | 1MB 8路 / 16MB 16路 ,l2-slices=4 |
经典三级层次 |
| BPU | branchPred |
DecoupledBPUWithBTB()(各子预测器取 SimObject 默认值) |
V2 未在脚本里逐个 enable 子预测器 |
| 时钟 / 内存 | cpu-clock / mem-type |
3GHz(非 ecore)/ DRAMsim3 | 频率与内存模型 |
V2 的调度器形态是典型的"4 个整数 IQ + 3 个 load IQ + 2 个 sta + 2 个 std + 3 个浮点 IQ ",并且没有 SIMD/向量 IQ,浮点结果不参与整数唤醒网络------这是 V2 与 V3 后端最大的结构性差别。
三、昆明湖 V3 的参数(kmhv3.py)
kmhv3.py 的 __m5_main__ 先改全局,再调 setKmhV3Params():
args.bp_type = 'DecoupledBPUWithBTB'
args.l2_size = '2MB' # V2 默认 1MB
args.l3_size = '32MB' # V2 默认 16MB
args.kmh_align = True
args.cdp_use_dynamic_degree = False
args.cdp_accuracy_threshold = 0.05
args.cdp_use_accuracy_dependent_alignment = False
args.cdp_use_sv48 = True
setKmhV3Params(args, test_sys)
setKmhV3Params() 逐块覆盖:
前端 :fetchWidth = 32(取指块翻倍)、fetchQueueSize = 64、iewToFetchDelay = 4、commitToFetchDelay = 4(注释写明是为"resolved update,squash 后再训练分支")、fetchToDecodeDelay = 3、decodeWidth = 8、enable_loadFusion = False、enableConstantFolding = False。
重命名 :renameWidth = 8、phyregReleaseWidth = 8、numPhysIntRegs = 224(与 V2 相同)、numPhysFloatRegs = 256(+64,为向量/浮点让路)、EnablePHASTMDP = False(仍用 store set 而非 PHAST)。
分派 :numDQEntries = [8,8,8]、dispWidth = [8,8,8]------注意容量比 V2 的 32,16,16 小 ,因为 V3 走 enableDispatchStage=False 路径,实际退化为每周期 8 条的直通约束。
调度器 :换成 KMHV3Scheduler() ------ 6×intIQ(16项) + 6×memIQ(ld0/1/2 + sta0/1 + std0/1, 16项) + 4×fpIQ(18项) + vecIQ0(42项,5 个 SIMD 发射口) ;唤醒网络升级为 3 条通道(fpIQ0 也能唤醒 int/mem,fp 能唤醒 std)。同时脚本里 disableAllRegArb()、enableMainRdpOpt = False、intRegfileBanks = 1 (类里默认是 2,这里被显式按回 1)------说明多 bank 寄存器堆与读仲裁建模在对齐配置下故意没开。
ROB :numROBEntries = 352(V2 的 2 倍多)、RobCompressPolicy = 'none'(关掉 V2 的 ROB 压缩 )、CROB_instPerGroup = 2、robWalkPolicy = args.rob_walk_policy(走命令行)。也就是说 V3 是靠"堆更大的物理 ROB"而不是压缩来扩窗口。
LSU/LSQ :LQEntries = 120、SQEntries = 64、StoreQueueMultiple = 2、RARQEntries = 96、RAWQEntries = 56、SbufferEntries = 16、SbufferEvictThreshold = 8、sbufferBankWriteAccurately = True (sbuffer 写内存要查 bank 冲突,比 V2 精确)、store_prefetch_train = False(与 V2 在 kmh_align 下一致)。
BPU(V3 变化最集中):
ftq_size = 64、fsq_size = 64;- 逐个显式打开:
ubtb / abtb / microtage(usingS3Pred=True) / mbtb / tage / ittage / mgsc / ras全部enabled = True; - 三者
trainingStage = "Resolve"(BTB/TAGE/ITTAGE 都在 Resolve 阶段训练); mgsc.forceUseSC = True、mgsc.allowMissingTageInfo = True;--standalone_sc时会关掉 microtage 与 tage(做消融实验);- TAGE 可切换
BTBTAGEUpperBound(usePathHashHistory=True)。
缓存:
- L1:
icache = dcache = 64kB,dcache.tag_load_read_ports = 100(等效不限制 tag 读端口)、mshrs = 16、do_fast_writeline = True、simulate_dcache_refill = True; - L2:2MB / 8 路 / 4 slice ,每 slice 512KB →
XSDRRIPRP(mode=2, num_sets=1024)(DRRIP 替换策略);data_sram_banks = 1、dir_sram_banks = 1、pipe_dir_write_stage = 3、dir_read_bypass = False;wpu = NULL、prefetch_can_offload = False; - L2 总线:
forward_latency = 3、response_latency = 3、hint_wakeup_ahead_cycles = 1(源码注释写着3->0、1->0,是等 RTL 落地后要改回 0 的保守值),并开了 DCache→L2 双端口(req/resp 各 2/cycle); - L3:32MB 、
mshrs = 64、do_fast_writeline = True、num_slices = 4; - MMU:ITB/DTB 的
enable_l1_direct_compression与 PTW 级数限制(setPtwLevelLimitParams)。
四、V2 vs V3 逐项对比
| 维度 | 昆明湖 V2 | 昆明湖 V3 | 变化解读 |
|---|---|---|---|
| 取指宽度 | 16 | 32 | 取指块翻倍,喂得动 8 宽译码 |
| 取指队列 | 48 | 64 | 容纳更长的取指流水 |
| 重定向延迟 | iew→fetch 1 / commit→fetch 3 | 4 / 4 | 为 resolved update(squash 后训练)加长,更接近 RTL 时序 |
| 译码 / 重命名 | 6 / 6 | 8 / 8 | 从 6 宽升级到 8 宽,这是 V3 最核心的代际变化 |
| 物理寄存器 | 224 / 192 | 224 / 256 | 浮点寄存器 +64 |
| ROB | 160,压缩策略 kmhv2(6 条/组) |
352,none,2 条/组 |
V3 放弃压缩,直接用更大的物理 ROB 换窗口 |
| 提交 / 释放宽度 | 8 / 6 | 8 / 8 | 释放宽度追平提交宽度 |
| 调度器 | KunminghuScheduler:4 intIQ(24) + 7 memIQ + 3 fpIQ | KMHV3Scheduler:6 intIQ(16) + 6 memIQ + 4 fpIQ + **vecIQ(42, 5 发射口)** | V3 整数 IQ 更多更小、分离 sta/std、首次引入向量 IQ |
| 唤醒网络 | 2 通道(fp 孤立) | 3 通道(fpIQ0 可唤醒 int/mem,fp 可唤醒 std) | 跨域唤醒更激进 |
| 寄存器堆 bank | 默认 | 显式 1(类默认 2 被按回) | 多 bank 建模暂未启用,属"对齐 RTL"的保守设定 |
| LQ / SQ | 72 / 56 | 120 / 64 | 访存窗口大幅扩大(+66% / +14%) |
| RARQ / RAWQ | 72 / 32 | 96 / 56 | 违例检测队列同步扩大 |
| sbuffer | 16 / 阈值 7 / 不查 bank 冲突 | 16 / 阈值 8 / 精确查 bank 冲突 | V3 建模更精细 |
| L1D | 64kB,默认参数 | 64kB + mshrs 16 + tag 读口 100 + fast writeline + refill 建模 | V3 显式建模 refill 与写线 |
| L2 | 1MB / 8 路 / 4 slice,fast writeline 关 | 2MB / 8 路 / 4 slice + XSDRRIP + 双端口总线 + fast writeline 开 | 容量翻倍、替换策略升级、端口带宽翻倍 |
| L3 | 16MB / 16 路 | 32MB / mshrs 64 / 4 slice | 容量翻倍 |
| BPU | 子预测器取默认值 | uBTB/ABTB/MicroTAGE/MBTB/TAGE/ITTAGE/MGSC/RAS 全开,统一 Resolve 训练,MGSC 强制用 SC | V3 前端预测器族完整启用(MGSC 为新增统计校正器) |
| 依赖预测 | EnablePHASTMDP 默认 True |
显式 False | V3 仍走 store set |
| store 预取训练 | kmh_align 下关闭 | 显式 False | 一致 |
| 时钟 | 3GHz(ecore 2.4GHz) | 3GHz(沿用默认) | 一致 |
| CI 与跑分定位 | spec06 0.8c 覆盖率,Tier2 合入后回归 | spec06 0.3c,Align BTB 性能 CI;README 称 kmhv3 > 15 pts/GHz,idealkmhv3 > 20 pts/GHz | 覆盖率不同,分数不可直接横比 |
五、怎么读这组差异
- V3 是"6 宽 → 8 宽"的代际升级:译码/重命名/释放全线上 8 宽,取指块从 16 拉到 32,配套把 ROB 从 160 扩到 352、LQ 从 72 扩到 120,是一条完整的"加宽流水线 + 扩窗口"路线,不是零敲碎打。
- ROB 策略发生了反转 :V2 靠
kmhv2压缩策略省空间,V3 直接none+ 物理项数翻倍。说明 V3 RTL 侧没做 ROB 压缩,模型跟着 RTL 走。 - 后端结构最大的不同在向量与唤醒 :V3 新增
vecIQ0(5 个 SIMD 发射口)、把 sta/std 分离、fpIQ 从 3 个变 4 个并接入跨域唤醒网络;V2 完全没有向量 IQ。 - V3 的"保守"是刻意的 :
intRegfileBanks=1、enableMainRdpOpt=False、disableAllRegArb()、microtage.usingS3Pred=True、L2 总线延迟3(注释里标注将来改 0),都是为了对齐尚在开发的 V3 RTL 而暂时压住的性能开关 ------这也是为什么官方说 kmhv3 当前分数与 V2 接近,真正跑上限的是idealkmhv3.py。 - 跑分别跨覆盖率比:V2 用 0.8c、V3 用 0.3c,官方明确提示 0.3c 天然比 0.8c 高约 1 分、比 1c 高约 1.2 分 。
六、上手核对与改动建议
- 核对真实生效值 :跑完后直接看
m5out/config.ini,比读脚本可靠(脚本里的值还可能被命令行--xxx再次覆盖)。 - 改参数 :核心宽度/队列在
configs/example/kmhv3.py的setKmhV3Params()改;V2 的对应值要去src/cpu/o3/BaseO3CPU.py改默认(或同样在 kmhv2.py 里加覆盖);调度器改configs/common/FUScheduler.py;缓存容量/预取器用命令行--l2_size、--l1d-hwp-type、--l2-wrapper-hwp-type即可。 - 性能探索 别在 kmhv3.py 上做:想看 V3 性能上限用
configs/example/idealkmhv3.py(对应 CI 的-perf触发分支);要继续维护 V2 相关配置,官方建议切到KMH-V2-CONFIG分支 。 - 批量跑 :
util/xs_scripts/parallel_sim.sh+ workload 列表,每行 6 个字段------名字、切片路径、skip、功能预热、详细预热、采样指令数(单位 M 指令,常见0 0 20 20)。
以上数值取自
xs-dev分支当前代码(BaseO3CPU.py / kmhv2.py / kmhv3.py / FUScheduler.py / Options.py)。XS-GEM5 迭代很快,V3 相关参数尤其可能随 RTL 对齐推进而变动,建议以你本地代码和m5out/config.ini为最终依据。