Skip to content

跨独立 Queue 的关联消息可能错过交互 #11

Description

@hmljy2020

问题描述

当一个对象和针对该对象的状态更新通过两个独立 Queue 传递时,两条路径可能因延迟或反压不同而错过交互。

即使每个 Queue 内部保持 FIFO,也无法保证两个 Queue 之间的全局顺序:

Object(X) ── Queue A ──┐
├── Consumer
Update(X) ── Queue B ──┘

可能出现:

发送顺序:Object(X) → Update(X)
到达顺序:Update(X) → Object(X)

如果 Consumer 只将 Update(X) 应用于已经驻留的对象,并且不保存更新状态,那么稍后到达的 Object(X) 将永久错过
该更新。

DavinciOO 示例

DavinciOO 中,ReadyTable 通过两条独立路径向 IssueQueue 发送指令和 wakeup:

ReadyTable ── ready_to_issue_q ──> IssueQueue

└────── issue_wakeup_q ─────> IssueQueue

可能发生以下时序:

  1. 指令 I 进入 ready_to_issue_q。
  2. IssueQueue 已满,I 因反压滞留在 Queue 中。
  3. I 等待的 tag 完成,ReadyTable 发出 wakeup。
  4. wakeup 经 issue_wakeup_q 先到达 IssueQueue。
  5. IssueQueue 只 wakeup 内部已经驻留的 entries,此时其中没有 I。
  6. I 随后才从 ready_to_issue_q 进入 IssueQueue。

如果没有额外机制,I 将错过 wakeup,并一直保持 not-ready。

当前实现

当前 DavinciOO 不会真正丢失该 wakeup,因为:

  • ReadyTable 将完成 tag 持久记录在 ready_tags_ 中;
  • 指令进入 IssueQueue 时调用 RefreshSourceReady();
  • IssueQueue 重新查询 ReadyTable,而不是只依赖之前经过的 wakeup 消息。

因此当前协议实际是:

IQ resident 指令:通过 wakeup 消息更新
中间 Queue 中的指令:进入 IQ 时重新查询 ReadyTable

设计要求

对于通过独立 Queue 传递的关联对象和更新,系统必须至少提供一种保证:

  • 持久保存最新状态,并在对象到达时重新查询;
  • 缓存尚未匹配的更新事件;
  • 将关联消息放入同一个有序通道;
  • 使用版本号或 epoch 识别新旧状态。

否则,反压或路径延迟可能导致 lost wakeup、lost invalidation 或类似的状态同步错误。

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:acirAgentic Circuit, ACIR, ACSim, and gfsim

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions