本文结合无线双向中继网络例子分析The ONE仿真器消息的发送与接收。之前的分析是函数调用关系,自己并不十分明白。直到这次,two-way relay networks产生的仿真结果有悖于逻辑,遂跟踪分析之,才算真正搞明白The ONE消息的发送与接收。

1. 仿真场景及奇葩结果

1.1 仿真场景

以无线双向中继网络为例,关于如何创建可参考文章《创建自定义网络拓扑》。这里,updateInterval为1秒(本人修改了源代码,使得每隔updateInterval,所以节点只更新一次,即处理完事件后,不updateHosts)。

无线双向中继网络

(1)节点更新顺序固定

Optimization.randomizeUpdateOrder = false

假设每次updateInterval,更新节点的顺序是固定的,即按照场景创建的顺序,本例为A、B、R。仿真结果如下:

无线双向中继网络节点更新顺序固定

图1 节点更新顺序固定的仿真结果

可见,消息产生间隔为1s时,居然没有一个包被传递,有悖于逻辑,也不符合实际场景。

(2)节点更新顺序随机

固定节点更新顺序的结果,仔细分析就出来了。很自然就想,如果更新顺序随机,也许就不会这样。然而,实际情况还是那样,仿真结果如下:

无线双向中继网络节点更新顺序随机

2. 分析仿真结果

如果够细心的话,会发现上图的仿真结果还有一个问题。理论上来说,A--R--B,需要4 emissions就可以完成消息的传输(A-->BB-->A),然而The ONE却需要5 emissions(见图1,msgInterval为5时,delivery_prob才接近1)。同理,对于xor网络编码,理论上只需要3 emissions,然而The ONE却需要4 emissions。

先给出结论:产生这些的根本原因是,The ONE的消息发送与接收都由发送者来触发。如A-->B,理论上,A发送消息,B接收消息。然而,对于The ONE,A发送消息,下一个update,检查该消息是否发送完成,若是,放到B的缓冲区,算是B接收到了消息。再有一点就是,节点做update时,做两件事:首先,检查消息是否发送完成;然后,如果有可能,再发送一个消息。

接下来,分析为什么会产生上述的奇葩结果。msgInterval为1秒。在0秒的时候,The ONE也更新所有节点,因为节点没有任何消息,所以什么事都不做。在1秒的时候,先处理消息产生事件,即产生消息,此时,A缓冲区有M1,B缓冲区有N1。接下来,更新所有节点。

2.1 节点更新顺序固定

1秒 (产生消息,A缓冲区有M1;B缓冲区有N1)

  • A发送M1给R(M1在B的incomingMessages,即on the way),
  • B尝试发送消息N1给R,但在checkReceiving检查R能否接收消息,因为R正在接收来自A的消息,所以什么都不做
  • R的A-R信道被占用,所以也什么事都不做

2秒(产生消息,A缓冲区有M2,M1;B缓冲区有N2,N1

  • A完成M1的传输,即将M1放入R的缓冲区;(现在所有的信道都是空闲的)紧接着,A尝试发送M2给R,又成功占用了。可见,每次都是A占用信道A-R,导致其他节点,没有机会发送消息。整个仿真,都是A不停地给R发送消息,但悲剧的是,一直到不了B。这也许就是世界上最遥远的距离:-(

2.2 节点更新顺序随机

对于随机的节点更新顺序,道理类似,取决于A和B谁先获得发送权。如果A取得发送权,情况跟2.1是一样的,无论后面的更新顺序如何,都一直是A在发送消息,反之亦然。

3. 如何破

经过上述的分析,产生这些问题的本质原因是消息的发送与接收都由发送者触发,且发送者先检查消息是否送达,而后如果有可能,就发送消息,占用信道。

至此,我已将The ONE源码改得面目全非了。。。

本文系Spark & Shine原创,转载需注明出处本文最近一次修改时间 2022-03-27 15:14

results matching ""

    No results matching ""