计算机体系结构 34:有界处理器集成

核心问题

参考执行、流水线时序和缓存延迟接在一起后,怎样证明加速结构没有改变程序的提交结果?最小可检查条件是:参考模型与流水线产生同序、同值的提交事件;延迟只改变周期;故意移除正确性机制时,差分检查必须失败。

附件:逐提交轨迹、参考解释器与流水线模型和批次命令源码。

范围与证据等级

证据等级为教学时序模型。有限程序支持 addi、lw、add、sw、bne,分别经顺序参考解释器和独立的有序发射/提交路径执行;原有求和、步长 4/16 和 load-use-store 四例之外,增加同址 store-load 与 x0 写入两组反例。它没有实现 32 位溢出、完整 RV32I、异常、MMU、乱序、多核或真实 DRAM。

缓存只有两行,每行 16 字节,记录 block、命中、缺失和固定 miss 延迟。数据值仍由架构 memory 字典提供,因此模型没有验证完整的 write-back 数据层级,也没有证明脏块最终到达 DRAM。

核心案例:结果相同,时间不同

load-use-store 案例初始 memory[16]=7,另设 memory[0]=0 供故障注入的错误地址读取。程序把 16 写入 x1,从地址 16 读取 7 到 x2,计算 x3=14,再把 14 写到地址 32。顺序解释器与流水线各独立产生四条提交,逐项比较 PC、值、地址和最终状态;循环案例各提交 17 条事件,最终 x4=6。

load-use-store 的两次访存落在不同 cache block,模型得到 2 miss、0 hit;包含填充与一次 load-use 停顿的发射/提交轨迹长 9 拍,每次 miss 增加 4 拍,得到模型总时长 17 拍。步长 4 的三次访存只缺失一次,步长 16 则缺失三次;同样 17 条提交,对应的模型总时长分别为 28 与 36 拍。

当 memory[0]=0,先 addi x1,x0,7,再 sw x1,0(x0); lw x2,0(x0),load 必须看到尚未提交但更早发射的 store,最终 x2=7;模型从待提交的同址 store 取最近的值。addi x0,x0,7; addi x1,x0,1 必须保持 x0=0、x1=1;写 x0 的指令仍提交零值,不产生对后续指令的数据冒险。

原有故障注入同时关闭前递和互锁,使 lw 从旧基址 0 读取,依赖它的 add 得到 x3=0;另一变体把 x3 的写回值翻转一位。两个错误仍在逐提交比较中被检出。只关闭前递但保留互锁可以得到较慢的正确实现,不属于这两个负例。

模式:提交状态与时间状态分账

1
2
正确性:commit_reference == commit_timing
性能:cycles = base + declared_stalls

流水线、缓存和更复杂的模拟器都应分别维护这两本账。周期相同不能证明值正确,提交一致也不能证明时序接近真实硬件。

验收结果

从仓库根目录运行 python3 examples/computer-architecture/run_batch.py 34,六组参考/流水线提交轨迹及最终状态一致;两类实际错误变体分别与参考轨迹不一致,否则命令非零退出。store-load 例的发射/提交为 7 拍,另加一次固定 cache miss 的 4 拍,报告为 11 拍;这不是逐拍建模的真实 miss 停顿。cache 只记元数据与附加延迟,不含 write-back 数据传播。合并命令 34-35 还复核第 35 篇本地原始归档。

练习

若第二次访问改到地址 20,按当前 cache 参数重新计算 hit/miss 和总拍数。

为什么“关闭前递后结果仍正确”不能证明前递没有用?

模式速查

检查 能证明 不能证明
提交值逐项相等 本程序架构结果一致 完整 ISA 合规
cache 元数据轨迹 题设 hit/miss 与延迟 write-back 数据传播
注入负例被检出 差分器能抓住该故障 覆盖所有冒险

一手参考资料