Skip to content

远程调用与消息传递 ​

在 Monarch 中,调用 Actor 的方法不是函数调用,而是一次消息传递。官方把 call、broadcast 这些调用方式称为"副词"(adverb)——它们修饰 endpoint 结果的处理方式。

1. call_one:调用单个 Actor ​

python
from monarch.actor import Future

# 假设 counter 是上一章在 this_proc() 里启动的单个 Actor
fut: Future[int] = counter.get_value.call_one()
value: int = fut.get()

print(f"Counter value: {value}")
  • 消息异步发送,立即返回 Future[int],发送者可以继续做别的事;
  • fut.get() 阻塞等待结果;在 asyncio 上下文中也可以 await;
  • call_one 断言你明确知道目标只有一个 Actor。

2. broadcast:广播给整个 Mesh ​

当你持有的是一组 Actor(ActorMesh)时,一条消息就能发给所有成员:

python
# 通知 8 个 Counter 全部 +1,不等待响应
counters.increment.broadcast()

broadcast 是"发射后不管"(fire-and-forget):它不返回可等待的 Future。但所有消息(包括广播)都保证按发送顺序送达。

3. call:广播并收集全部响应 ​

想拿到所有 Actor 的返回值,用 call:

python
# 8 个 Actor 各自返回当前值,聚合成一个列表
results = counters.get_value.call().get()
print(results)  # [1, 1, 1, 1, 1, 1, 1, 1]

事实上 call_one 就是 call 的特例——当你确定只有一个 Actor 被寻址时使用。

4. 流式响应与随机选择 ​

stream() 让你边到边处理,不必等全部响应凑齐:

python
for future in counters.get_value.stream():
    result = future.get()
    print(f"Got result: {result}")
    process(result)

choose() 则从 Mesh 中随机挑一个 Actor 来响应,适合无状态、可互换的服务型 Actor:

python
# 每次调用独立均匀随机选择一个 Actor
result = workers.compute.choose(data).get()

⚠️ choose 不感知负载,只在大量调用下近似均衡;需要精确控制某个 rank 时,应该切片后用 call_one。

5. 消息顺序保证 ​

Monarch 保证 FIFO(先进先出)消息顺序:

  • Actor A 先后发给 Actor B 消息 M0、M1,则 B 一定先收到 M0 再收到 M1;
  • 发给 mesh 的批量消息,等效于逐个送达每个目标;
  • 每个 Actor 串行处理自己的消息:处理完当前消息才会处理下一条;
  • 同一进程内不同 Actor 并发处理各自的消息。
python
actor.method1.call_one(arg1)  # 消息 M1
actor.method2.call_one(arg2)  # 消息 M2
actor.method3.call_one(arg3)  # 消息 M3
# Actor 严格按 M1 → M2 → M3 的顺序处理

6. 为什么是异步的? ​

异步设计是高性能分布式的关键:

  1. 隐藏延迟:网络传输需要时间,异步让 CPU 在等待网络 IO 时继续工作;
  2. 流水线并行:连续发送多个请求(例如多个 mini-batch),让 GPU 保持忙碌,不必每步停下来同步。
python
futures = []
for i in range(5):
    # 连续派发 5 个任务,几乎瞬间完成
    futures.append(counters.increment.call())

# 统一收集结果
for i, fut in enumerate(futures):
    fut.get()

副词速查表 ​

副词目标返回典型场景
call_one()单个 ActorFuture[Result]点对点调用
call()全部 ActorFuture[List[Result]]广播 + 收集响应
broadcast()全部 Actor无(不等响应)触发副作用、最高吞吐
choose()随机一个Future[Result]无状态服务均衡
stream()全部 ActorIterator[Future]响应边到边处理
rref()全部 Actor分布式张量引用张量计算(见中级教程)

接下来,让我们把视角从单个 Actor 拉远,看看 Monarch 最核心的抽象:Mesh。

Monarch中文教程