执行单元与数据通路:从 Issue 到 Writeback¶
本文解释 XiangShan DefaultConfig 后端执行侧:Issue Queue 如何选择 uop、操作数怎样经过物理寄存器文件和旁路网络、整数/浮点/向量功能单元如何分配端口,以及为什么“操作数 ready”仍可能不能发射。目标是把软件性能现象映射到可验证的硬件资源。
版本与结论边界¶
- 固定提交:
c7b373b - 默认配置:
DefaultConfig,EnableBackendV2Config=false。Parameters.scala:117-153 - 文中“延迟”若来自
FuConfig,只表示配置中的流水延迟,不等于从软件视角测得的总 latency。 - 源码事实 / 软件侧推导 / 待验证的含义与《后端总览》一致。
执行侧全景¶
flowchart LR
DIS["Dispatch"] --> IQI["Integer / Memory IQ"]
DIS --> IQF["FP IQ"]
DIS --> IQV["Vector IQ"]
IQI --> ARBI["Oldest-ready + FU/WB gate"]
IQF --> ARBF["Oldest-ready + FU/WB gate"]
IQV --> ARBV["Oldest-ready + FU/WB gate"]
ARBI --> RFI["Int RF / RegCache"]
ARBF --> RFF["FP RF"]
ARBV --> RFV["VF / V0 / VL RF"]
RFI --> BN["Forward / Bypass"]
RFF --> BN
RFV --> BN
BN --> INT["ALU / MUL / DIV / BJU"]
BN --> FP["FALU / FMAC / FDIV / FCVT"]
BN --> VEC["Vector arithmetic + OG2"]
BN --> LSU["LDU / STA / STD / VLSU"]
INT --> WBA["Per-regfile WB arbiters"]
FP --> WBA
VEC --> WBA
LSU --> WBA
WBA --> PRF["Physical Register Files"]
WBA --> ROB["ROB completion"]
LSU -. "cancel / replay" .-> IQI
VEC -. "OG failure" .-> IQV
每个执行 Region 都由 Issue Queue、DataPath、BypassNetwork、ExuBlock 和写回路径构成。Region.scala:38-57 ExuBlock 按参数实例化执行单元,并导出 BJU resolve、跨域数据和每个 EXU 的 fire 统计。ExuBlock.scala:18-95
DefaultConfig 的执行端口地图¶
以下是源码配置,不是对峰值吞吐的承诺。完整定义见 Parameters.scala:341-474。
整数、分支与标量访存¶
| Issue block | 功能单元 | 支持的主要 FuType | 关键写回 |
|---|---|---|---|
| Int IQ0 | ALU0 + BJU0 | ALU、CSR、Fence;Branch、Jump | Int WB0 |
| Int IQ1 | ALU1 + BJU1 | ALU、Div;Branch、Jump | Int WB1 |
| Int IQ2 | ALU2 + BJU2 | ALU、I2F、I2V、VSet;Branch、Jump | Int WB2,并跨写 FP/VF/V0/VL |
| Int IQ3 | ALU3 | ALU、BKU | Int WB3 |
| Int IQ4 | ALU4 | ALU、Mul | Int WB4 |
| Int IQ5 | ALU5 | ALU、Mul | Int WB5 |
| Load IQ0–2 | LDU0–2 | 标量 Load | Int WB6–8,也可写 FP |
| Store addr IQ0–1 | STA0–1 | Store 地址 | 无普通数据目的写回 |
| Store data IQ0–1 | STD0–1 | Store 数据 | 无普通寄存器写回 |
直接的软件含义:
- 简单整数 ALU 有 6 条候选通路,但 Div 只在 ALU1,BKU 只在 ALU3,Mul 只在 ALU4/5;特定 FuType 的真实吞吐远小于“6 ALU”。
- 分支/跳转有 3 个 BJU 候选,仍会受到共享 IQ、整数源读取和 redirect 仲裁限制。
- 有 3 个 LDU 不代表每周期必然完成 3 个 load;LQ、TLB、DCache bank、MSHR、地址依赖、写回端口和 replay 都可能限速。
浮点¶
| Issue block | 功能单元 | 能力 |
|---|---|---|
| FP IQ0 | FEX0 | FALU、FMAC、FCVT、FCMP、F2V;可跨写 Int/VF/V0 |
| FP IQ1 | FEX1 | FALU、FMAC、FDiv |
| FP IQ2 | FEX2 | FALU、FMAC、FDiv |
| FP IQ3 | FEX3 | FALU、FMAC |
FDiv 仅出现在 FEX1/2;FCVT、FCMP 和 F2V 集中在 FEX0。混合这些操作时,不能只看“有 4 个 FP 执行单元”。
向量¶
| Issue block | 功能单元 | 能力 |
|---|---|---|
| Vec IQ0 | VFEX0 | 常用向量整数/浮点/乘加/转换/置 VL/移动 |
| Vec IQ1 | VFEX1 | 常用向量算术,另含 VFDiv、VIDiv |
| Vec mem IQ0 | VLSU0 | 普通及 segment 向量 Load/Store |
| Vec mem IQ1 | VLSU1 | 普通向量 Load/Store |
向量算术通过额外的 OG2 阶段确认,向量访存进入 memory Region 后再合并写回。Region.scala:624-731 Og2ForVector.scala:15-70
Issue Queue:ready、selected、issued、success 是四件事¶
源码事实¶
IQ entry 分别保存 valid、issued、源 ready 和可发射状态。IssueQueue.scala:203-240
选择逻辑不仅检查所有源是否 ready,还检查目标 EXU 是否支持该 FuType、EXU 是否忙、预计写回端口是否忙。IssueQueue.scala:416-472
在符合条件的 entry 中,AgeDetector 优先选择程序顺序较老者。IssueQueue.scala:481-604 NewAgeDetector.scala:26-78
Div/FDiv 等不确定延迟单元使用专门的 wakeup queue;固定延迟结果则可按配置提前调度 wakeup。IssueQueue.scala:617-857
不同类型的 uop 会在 OG1、OG2、s0、s1、s2 或更后阶段才得到 finalSuccess;失败反馈会令 entry 保留或重试。IssueQueue.scala:1047-1083
软件侧推导¶
srcReady=1只能证明依赖满足,不能证明有可用执行端口、RF 读口或 WB 时隙。- “issue 次数”对 load/向量工作可能包含最终失败的尝试;分析时应同时看 final success、cancel/replay。
- oldest-ready 能改善公平性,但不会消除单一 FuType 的端口瓶颈,例如 Div、BKU、FCVT 或 segment VLS。
IQ 自带 enqueue/dequeue、占用、ready、issue 和数据来源统计。IssueQueue.scala:1092-1189
功能单元延迟:配置值与实测值的边界¶
CertainLatency 的总配置延迟由基础值和 extra latency 组成;UncertainLatency 用于除法、访存等完成时间不固定的操作。FuncUnit.scala:18-45
| FuType | 源码配置 | 备注 |
|---|---|---|
| ALU / Branch / Jump | 0 | 仍有 RF、选择、redirect 等外部阶段 |
| Mul | 2 | 默认有两条 Mul 候选通路 |
| Div | 不确定 | 仅 ALU1 支持 |
| I2F | 2 + 1 | 跨寄存器域 |
| FALU | 1 | |
| FMAC | 3 | |
| FCVT | 2 + 1 | 跨域结果可能共享低优先级端口 |
| FDiv | 不确定 | 仅 FEX1/2 |
| VIALU | 1 | 向量算术还经过 OG2 |
| VIMAC | 2 | 向量算术还经过 OG2 |
| VFMA | 3 | 向量算术还经过 OG2 |
| VFDiv / VIDiv | 不确定 | 集中在 VFEX1 |
| Vector Load/Store | 不确定 | 受 memory pipeline 和 replay 影响 |
配置来源:FuConfig.scala:229-386、FuConfig.scala:545-900。向量 needOg2 和跨域额外延迟的组合见 ExeUnitParams.scala:188-269。
待验证: 上表不能直接作为 llvm-mca、编译器 scheduling model 或手工汇编的最终 latency。应在目标生成 RTL 上测量 issue→wakeup、issue→WB 和 issue→commit,并区分依赖 latency 与吞吐。
物理寄存器文件与读取仲裁¶
寄存器文件的读地址寄存一拍,支持多写口;整数 x0 被硬连为零。另有 banked RF 实现。Regfile.scala:67-213
DataPath 分别实例化整数 RF/RegCache、FP RF、VF/V0/VL RF,并在 IQ 到 RF、RF 到执行输入之间执行端口仲裁。DataPath.scala:280-424 若读取或写回端口被阻塞,s0.ready 不能成立,失败会反馈 IQ。DataPath.scala:488-648
关键观测量包括:
IntRFReadBeforeArb/IntRFReadAfterArbFpRFReadBeforeArb/FpRFReadAfterArbVfRFReadBeforeArb/VfRFReadAfterArb- 每 EXU 的 forward、bypass、RegCache、RF、zero、immediate 来源
这些计数在 DataPath.scala:717-766 定义。
软件侧推导¶
BeforeArb - AfterArb 的持续差距,是 RF bank/读口压力比“高 IQ occupancy”更直接的证据。若 ready uop 很多、issue 很低且该差距明显,应优先研究寄存器读取压力、指令混排和跨域转换,而不是先归因于数据依赖。
Forward、Bypass 与 RegCache¶
BypassNetwork 支持同周期 forward、寄存一级 bypass,以及 vector/load 到 vector/memory consumer 的 bypass2。BypassNetwork.scala:103-143
每个源操作数可从 forward、bypass、bypass2、RF、RegCache、V0、zero 或 immediate 中选择。BypassNetwork.scala:180-220
软件侧推导¶
- 短整数依赖链如果稳定命中 forward/bypass,可避免真正读取 RF;但消费者端口仍必须可用。
- Load→use、FP→Int、Int→FP、Vector→Scalar 等路径的实际 latency 取决于跨 Region wakeup、旁路级和写回仲裁,不能套用简单 ALU 的经验值。
- RegCache 命中率和 bypass 来源比例可帮助区分“物理 RF 压力”与“纯执行端口压力”。
Writeback:执行完成后仍可能排队¶
写回先按 Int、FP、VF、V0、VL 寄存器文件拆分并仲裁。向量 load 数据在进入公共写回前还要经过合并。WbArbiter.scala:112-253
不确定延迟执行单元允许被 backpressure;固定延迟单元若发生同端口碰撞则触发断言,要求参数配置从结构上避免冲突。只有真正 fire 的结果才会更新物理寄存器状态和 ROB。WbArbiter.scala:292-386
RFWBConflictChecker 为连续失败请求提高优先级,避免长期饿死。RFWBConflictChecker.scala:53-110
软件侧推导¶
- Div、FDiv、Load 等不确定延迟结果同时返回时,可能在共享写回口排队。
- I2F、F2I、FCVT、F2V、向量标量提取等跨域操作会使用其他寄存器文件的端口,有些配置为较低优先级;高密度转换代码需单独观察。
- “EXU fire 很高但提交没有提升”时,应检查 WB fire、ROB 完成和 ROB head,而不是把发射率当作完成率。
整数、浮点、向量执行的边界¶
整数与分支¶
ExeUnit 根据配置实例化多个 FunctionUnit,在输入、控制和数据路径上加入相应流水级,并统一选择 Int/FP/Vec/V0/VL 结果。ExeUnit.scala:55-69 ExeUnit.scala:146-280
BranchUnit 检测方向或目标不一致并生成 redirect;JumpUnit 检查预测/固定目标并反馈误预测与训练信息。BranchUnit.scala:53-87 JumpUnit.scala:37-85
性能上需区分:分支执行端口是否饱和、预测是否错误、redirect 是否被更老事件覆盖,以及恢复 walk 是否成为主要代价。
浮点与跨域转换¶
FP 域既有确定延迟 FALU/FMAC,也有不确定延迟 FDiv。FEX0 还集中承担 FCVT、FCMP、F2V,并可能写回 Int/VF/V0 文件。默认 wakeup 拓扑允许 LDU 唤醒 FP consumer,并允许 FP 结果唤醒 store-data consumer。Parameters.scala:478-498
软件调优时,混合 FP compare/convert、FMA 和除法可能造成不均衡端口压力,即使总体 FP 指令比例不高。
向量算术与访存¶
向量算术写 VF,也可能写 V0、VL、Int 或 FP;其结果经过 OG2。向量访存 uop 则送到 memory Region,load 数据合并后返回向量写回。Region.scala:624-731
因此向量性能必须同时检查:
- Vec IQ 与特定 VFEX/VLSU 是否饱和。
- VF、V0、VL FreeList 是否短缺。
- old-vd、mask 和 VL 是否形成额外依赖。
- VF/V0/VL RF 读写仲裁。
- VLSU、DCache、TLB、LSQ 和 load replay。
诊断流程:从症状定位到硬件资源¶
flowchart TD
A["IPC 或提交率低"] --> B{"ROB 接近满?"}
B -->|是| C{"ROB head 等什么?"}
C -->|Load| D["查 cache/TLB/LQ 与 replay causes"]
C -->|Div/FDiv/VDiv| E["查长延迟依赖链与专用端口"]
C -->|其他 EXU| F["查对应 IQ ready/issue/WB"]
B -->|否| G{"Rename/Dispatch stall 高?"}
G -->|FreeList| H["查 live range、展开、LMUL、提交延迟"]
G -->|IQ/LSQ| I["查队列占用与结构限制"]
G -->|否| J{"IQ ready 高但 issue 低?"}
J -->|是| K["查 FU busy、WB busy、RF Before/AfterArb"]
J -->|否| L["查数据依赖、wakeup 与前端供给"]
常见症状矩阵¶
| 现象 | 最有区分度的证据 | 典型解释 | 建议实验 |
|---|---|---|---|
| IQ valid 高、ready 低 | source-ready、select latency | 真实数据依赖或生产者长延迟 | 改变展开/调度;缩短关键依赖链 |
| ready 高、issue 低 | FU/WB busy、RF Before/After | 执行口、RF bank/读口或写回口竞争 | 改变指令混排;拆分跨域转换;降低同周期源读取 |
| issue 高、WB/commit 低 | WB fire、ROB completion/head | 不确定延迟 WB 争用或 ROB 头阻塞 | 分离 Div/Load/转换;检查返回突发 |
| Div/FDiv/VDiv head wait 高 | 对应 FuType latency、IQ occupancy | 专用长延迟单元或串行依赖 | reciprocal/strength reduction;增加独立工作 |
| 向量算术低吞吐 | VecIQ、OG2 success、VF RF | old-vd/mask/VL 或 VFEX 端口 | 调整 LMUL、tail/mask policy、展开 |
| 向量访存低吞吐 | VLSU、replay、cache/TLB | segment 单端口、未对齐、bank/地址依赖 | 对齐、改变 AoS/SoA、预取与访问顺序 |
| 分支多但 BJU 不忙 | mispredict、recovery、walk | 预测质量而非执行带宽 | 重排热路径、减少间接/数据相关分支 |
BackendV2Config:不要混用执行端口图¶
BackendV2Config 把 EnableBackendV2Config 置真,并将 Decode/Rename 缩到 6、ROB 缩到 208、RAB 改为 256,同时改变物理寄存器 bank 配置。Configs.scala:447-490
它通过 BackendV2SchdParams 替换 DefaultConfig 的 scheduler:整数 ALU 从 6 个缩为 4 个,Mul/BKU 合并进 ALU2/3;FP 从 4 个 FEX 缩为 3 个;仍保留 3 LDU、2 STA、2 STD、2 个向量算术单元和 2 个 VLSU。BackendParams.scala:544-703
Parameters.scala 根据 EnableBackendV2Config 在默认 scheduler 和 V2 scheduler 间选择。Parameters.scala:503-517
因此:
- 本文端口表仅适用于
DefaultConfig。 - V2 的 RF bank、端口编号、IQ 深度和 wakeup 图必须从
BackendV2SchdParams单独阅读。 BackendV2Config带弃用警告;除非目标 RTL 明确使用它,不应拿 V2 参数解释默认 XiangShan 性能。
待验证清单¶
- 用目标生成命令导出的最终参数确认 DefaultConfig 是否被 YAML、Config mixin 或本地 patch 覆写。
- 在仿真或 FPGA 上分别测量依赖 latency、执行吞吐、WB latency 和 commit latency;不要用
FuConfig单一数字代替四者。 - 确认
XSPerfverbose/debug 计数是否综合进目标、是否接入 PMU,以及 Linux perf 驱动是否暴露。 - 对固定延迟 WB 冲突断言、RF bank 仲裁和跨域优先级,用生成 RTL/波形验证;源码参数描述的是构造规则,不是运行时测量。
- 向量 load 的“最终成功”路径与标量 load 不同,应在波形中同时观察 OG2、memory response、merge 和 WB fire。