Unetstack中PoissonBehavior平均到达时间异常问题咨询
问题重现
- 仿真配置:基于DiscreteEventSimulator搭建,包含两个核心代理——使用
PoissonBehavior的源代理(按指定平均延迟生成DatagramReq发送至协议代理)、Dflood协议的两种变体(参考2013年MTS/IEEE OCEANS - Bergen论文Duplicate reduction with adaptive backoff for a flooding-based underwater network protocol) - 异常表现:与原文献一致的Dflood变体中,洪泛规则的最小/最大延迟参数会显著影响
PoissonBehavior的数据包生成速率,偏离预期值且差异远超随机波动范围;换用其他工作机制的协议,或把PoissonBehavior替换为TickerBehavior时,源代理生成数据包数量均符合预期;该问题在ProtocolChannelModel和BasicAcousticChannel中均会出现
可能原因分析
离散事件调度的资源挤占
DiscreteEventSimulator采用单线程事件调度模型,若目标Dflood变体因洪泛规则生成大量密集事件(如短间隔的重传调度、洪泛转发事件),会持续占据事件队列,导致PoissonBehavior的下一个数据包生成事件被延迟执行,最终拉低整体生成速率。而TickerBehavior是固定间隔触发,事件调度逻辑更稳定,不易受队列阻塞影响。仿真时钟推进异常
PoissonBehavior的下一个事件触发时间是基于当前仿真时钟计算的,若其他代理的大量事件堆积导致仿真时钟推进延迟或"跳跃",会直接干扰Poisson间隔的计算逻辑,使得实际生成速率偏离预期。隐式状态交互
虽看似无直接关联,但源代理可能间接感知到Dflood变体的运行状态:比如Dflood的洪泛导致信道持续繁忙,源代理若订阅了BusyNtf等信道状态通知,可能存在未被注意到的逻辑(如临时暂停生成),进而影响PoissonBehavior的执行。
排查与解决建议
监控事件队列状态:添加仿真事件队列监控代码,实时查看事件堆积情况,确认是否是Dflood的事件挤占了调度资源:
sim.addSimulatorListener { event -> if (event instanceof EventQueuedEvent) { println "${sim.time}: 队列长度 = ${sim.eventQueue.size()}, 事件所属代理 = ${event.agent}" } }隔离验证Dflood影响:临时禁用Dflood代理的核心事件调度逻辑(保留空实现),测试
PoissonBehavior的速率是否恢复正常。若恢复,则可确认是Dflood的事件生成导致调度阻塞。确认PoissonBehavior时钟依赖:检查
PoissonBehavior的实现,确保其下一个事件时间是基于仿真时钟而非真实时钟计算——Unetstack默认使用仿真时钟,但自定义逻辑时可能误引入真实时钟依赖。调整事件优先级:若确认是队列阻塞问题,可为
PoissonBehavior的事件设置更高调度优先级,避免被低优先级事件挤占:scheduleEvent(time + nextInterval, { generateDatagram() }, Priority.HIGH)排查隐式交互逻辑:检查源代理代码,确认是否订阅了协议代理或信道的状态通知(如
DatagramNtf、BusyNtf),并存在基于这些状态调整生成速率的逻辑。
内容的提问来源于stack exchange,提问作者Viktor Lidström

