当前 Gem5 (v25.1.0.0) 开始支持分布式发射队列:

Dispatch 阶段(IEW::dispatch()),根据 Dispatch 阶段当前状态 dispatchStatus[tid] 决定下一步动作:

  • Running / Idle: 分派指令到 insts 数组:dispatchInsts(tid)
  • Unblocking: 分派指令到 skidBuffer dispatchInsts(tid) 并将来自 Rename 阶段的指令写入 SkidBuffer skidInsert(tid)unblock(tid)
  • 其余状态不做任何动作

分派指令实际执行时:(IEW::dispatchInsts): 循环遍历宽度以内可分派的所有指令

  • 如果遇到指令被冲刷(inst->isSquashed()): 则 continue 处理下一条指令
  • 如果当前指令对应的发射队列 InstQueue 满了(instQueue.isFull(inst)):
    阻塞整个 Dispatch 阶段: block(tid); 退出循环
  • 如果当前指令是访存指令或原子指令,对应的 LSQ 满了(instQueue.isFull(inst)):
    1
    2
    3
    4
    5
    6
    7
    8
    if ((inst->isAtomic() && ldstQueue.sqFull(tid)) ||
    (inst->isLoad() && ldstQueue.lqFull(tid)) ||
    (inst->isStore() && ldstQueue.sqFull(tid))) {
    ...
    block(tid);
    ...
    break;
    }
    阻塞整个 Dispatch 阶段;退出循环
  • 处理 HTM 指令:…
  • 正式开始分派指令
    • 分派原子指令: …
    • 分派 Load 指令: …
    • 分派 Store 指令: …
    • 分派 Barrier 指令: …
    • NOP 指令不分派,直接标记其执行完毕可写回
    • 分派剩余指令:…
  • 在最大分派带宽下分派结束后如果还有指令未分派,则阻塞 Dispatch 阶段,等待下一拍处理