云RAN(Cloud Radio Access Network)这词,在5G仿真圈里这两年出现的频率越来越高。但真正动手做过仿真的人应该都有体会:纸上谈架构是一回事,把BBU拆成CU和DU,再把CU的控制面和用户面劈开,塞进仿真拓扑里,又是另一回事。我最近在基于无线网络仿真平台做一套5G网络仿真项目,正好把云RAN架构从头到尾踩了一遍,从功能拆分到接口建模,从前传时延到同步失真,再到仿真脚本和参数收敛,攒了不少一手经验。这篇文章就把这套云RAN架构仿真的来龙去脉写清楚,包括工具选型、仿真拓扑设计、时延参数配置、脚本实现、结果验证,以及几个我从踩坑到修复的完整排查过程。不管你是刚开始搭建仿真环境的新手,还是已经在调参数但结果老是不对劲的老手,这篇都能给你一些参考。
1. 云RAN架构在仿真维度拆解成四层,比读标准文档直观十倍
搞5G网络仿真,最忌讳的就是直接把真实协议栈的复杂度全塞进仿真里。云RAN架构本身就不是一个单一实体,它由RU、DU、CU-CP、CU-UP等多个逻辑节点和一堆接口组成。在仿真环境里,第一步不是写代码,是把这个架构“翻译”成仿真能处理的模型层级。
1.1 从物理站到虚拟网元的映射关系
传统LTE仿真里,一个eNodeB就是一个节点,基站内部再复杂也不需要你建模。但5G云RAN不同,一个gNB在云RAN架构下是分布式的:RU负责射频前端和低物理层,DU负责高物理层、MAC、部分RLC,CU则分成控制面(CU-CP)和用户面(CU-UP)两个逻辑节点。这意味着仿真拓扑里,一个“基站”至少要被拆成4个仿真实体,还得分别部署在不同位置。
我建仿真模型时,实际映射关系是这样的:
- RU(Remote Unit)映射为射频节点,模拟覆盖范围、信道质量、射频收发。
- DU(Distributed Unit)映射为带有实时处理约束的计算节点,挂在RU上方,通过前传接口连接。
- CU-CP(Central Unit Control Plane)映射为控制面逻辑节点,管RRC、PDCP-C,只处理信令消息。
- CU-UP(Central Unit User Plane)映射为用户面逻辑节点,管PDCP-U、SDAP,承载业务数据。
这么拆完以后,普通gNB的所有用户面数据包路径就变成:UE -> RU -> DU -> CU-UP -> 核心网,控制面则是:UE -> RU -> DU -> CU-CP -> AMF。两层路径不一样,时延构成也不一样,仿真里必须分别建模,不能混着算。
1.2 三类接口与四段传输路径,仿真拓扑的核心骨架
云RAN架构仿真的另一个关键点是接口建模。接口不是一根线,它代表的是协议交互和传输时延两个维度。我仿真的拓扑里主要建模了三条接口链路:
| 接口 | 连接节点 | 承载内容 | 仿真建模侧重 |
|---|---|---|---|
| 前传(Fronthaul) | RU <-> DU | IQ采样数据、下行控制信令、时延敏感 | 带宽、时延抖动、同步误差 |
| 中传(Midhaul,F1接口) | DU <-> CU-CP/CU-UP | RRC信令、RLC/PDCP数据 | 传输时延、丢包、拥塞 |
| 回传(Backhaul,NG接口) | CU-CP/CU-UP <-> 5GC | NGAP信令、用户面PDU | 端到端时延、QoS策略 |
这里最容易漏掉的是“四段传输路径”的概念。实际业务从UE到核心网要经历:无线空口段、前传段、中传段、回传段。很多仿真项目只建了无线空口,把传输网当成零时延处理,这在传统一体化基站里勉强说得过去,但在云RAN架构里就是错误源头。我做仿真时把每一段都建模成独立的传输通道,每一段都能独立配置时延和带宽,这样后续做时延敏感业务分析时,才能定位到问题出在哪一段。
提示:仿真拓扑抽象层级做多了会拖慢运行速度,做少了又丧失云RAN架构特征。我实测下来,RU和DU之间那一层前传建模是这个架构最关键的特征,绝对不能省略。中传和回传段可以先用简化模型,等架构跑通了再加细。
2. 仿真工具选型,别一上来就走“全协议栈仿真”的高大上路线
云RAN架构仿真的工具选择,是我见过分歧最大的地方。有人用系统级仿真平台,有人用离散事件仿真器,还有人直接拿真实协议栈代码改。我的经验是:选择什么工具,取决于你要回答什么问题。
2.1 主流工具的五维对比
我把常见的工具按五个维度做了对比,这里给出一份参考表:
| 工具 | 建模粒度 | 云RAN架构支持度 | 仿真速度 | 上手成本 | 适用场景 |
|---|---|---|---|---|---|
| ns-3 | 分组级 | 需自己扩展,支持自定义节点和接口 | 较快 | 中等 | 协议机制验证、端到端时延分析 |
| OMNeT++ | 消息级 | 模块化好,适合自定义拆分 | 中等 | 较高 | 控制面协议交互、接口时序验证 |
| 系统级仿真平台(如自研或商用) | 链路级 | 取决于实现,通常需二次开发 | 较慢 | 高 | 覆盖、干扰、小区级性能评估 |
| OAI(OpenAirInterface) | 真实协议栈级 | 原生支持CU/DU拆分 | 很慢 | 很高 | 真实代码验证、硬件在环测试 |
| 自写离散事件脚本 | 自定义 | 完全可控 | 很快 | 取决于能力 | 特定问题验证、参数扫描 |
2.2 我最终选了什么,以及为什么
我这次项目最终没有用OAI,原因很直接:全协议栈拉仿真太慢了,我要扫参,一次跑20组时延配置和带宽配置,OAI跑一次得几个小时,根本扫不动。也没有用纯系统级仿真平台,因为我要细化到F1接口消息交互层,系统级仿真太宏观。
我最终用的是自定义离散事件仿真框架+简化的协议模型。核心思路是:不模拟每一个协议层的每一个函数,而是模拟“消息的生成时间、传播时延、排队时延、处理时延”。每一层功能抽象成时间轴上的处理事件。这样虽然丢失了LTE/NR协议栈的细粒度行为,却保住了云RAN架构极其敏感的时延特性。而对传输链路建模,我参考了网络仿真中常用的排队论模型,保证在拓扑结构有压力时,结果依然可信。
如果你做仿真是为了评估覆盖、干扰这类无线空口问题,那应该用系统级平台;如果你是为了验证CU-DU拆分后的信令流程是否走得通,那应该用OAI这类真实协议栈工具;但如果你像我一样,要评估云RAN架构下的前传时延如何影响业务质量、F1接口带宽如何影响同时在线用户数,那自写仿真反而是最灵活的选择。
3. 仿真拓扑里的一次完整数据面与信令面流程演练
这一节是全文最核心的干货。我直接用一套实际配置的仿真拓扑,把云RAN架构里一次数据面下行传输和一次信令面流程完整走一遍。你会看到哪些步骤消耗了时间,哪些参数一改就会影响结果。
3.1 数据面下行:从核心网到UE的分段时延构成
在云RAN架构仿真里,一个下行数据包的旅程是这样的(我按实际仿真参数标注时延):
- UPF把用户面数据经N3接口送给CU-UP,此时记为T0。仿真里这里设置初始到达时间戳。
- CU-UP处理:SDAP/PDCP加头、加密、排序,处理时延我设置为0.3ms。
- CU-UP通过F1-U接口发送给DU。这里经过中传网络,单向传输时延设为0.2ms。
- DU处理:RLC分段、MAC调度、HARQ重传管理,处理时延设置为0.5ms。
- DU打包成前传IQ数据发往RU,前传单向时延我设置为0.1ms。
- RU进行物理层处理并发射空口信号,射频处理时延0.2ms,空口传播时延按小区半径建模(按500米半径,约1.7us,远小于毫秒级处理时延,可忽略)。
所以单包下行时延在空载情况下就是:0.3 + 0.2 + 0.5 + 0.1 + 0.2 ≈ 1.3ms。这个数字很关键,因为它直接决定了你在配置URLLC类业务时能不能满足端到端5ms预算。如果核心网侧已经花费了2ms,那留给空口和传输的时间就更紧张了。
仿真代码里我使用了离散事件调度来传递数据包,关键事件类型大概长这样:
class F1UDataPacket: def __init__(self, pkt_id, timestamp, payload_size_bytes): self.pkt_id = pkt_id self.timestamp = timestamp self.payload_size_bytes = payload_size_bytes class F1UInterface: def __init__(self, bitrate_mbps, delay_ms): self.bitrate_mbps = bitrate_mbps self.delay_ms = delay_ms self.queue = [] def transmit(self, packet, current_time): self.queue.append(packet) # 计算排队时延 queue_delay_ms = sum(p.payload_size_bytes * 8 / (self.bitrate_mbps * 1e3) for p in self.queue) return current_time + self.delay_ms + queue_delay_ms这段代码虽然简化,但保留了F1-U最关键的三个时延成分:传输时延、排队时延、处理时延。我实测下来,模板里的queue_delay_ms就是F1链路带宽配置错误后最常见的问题爆发点。
3.2 信令面流程:RRC连接重配的F1AP交互
控制面我重点仿真的是RRC连接重配过程。在云RAN架构下,这条信令不仅要穿越空口,还要在CU-CP和DU之间走F1-C接口三次。仿真里我按如下顺序推进:
- UE上报测量报告 -> RU透传 -> DU经F1-C发给CU-CP(上行RRC消息封装在F1AP里)。
- CU-CP决策并生成新的RRC重配消息。
- CU-CP经F1-C下发到DU,DU解析F1AP得到RRC容器,再经空口发给UE。
- UE完成重配后回复RRC重配完成,原路返回CU-CP。
仿真里我对每个节点都设置了处理时延,尤其CU-CP的决策处理我设置为0.8ms,这个值直接影响切换和重配的端到端耗时。测试中我把这个值从0.8ms改成2ms,RRC连接重配的整体时延立刻从12ms涨到28ms,而且这个延迟在测速指标里很难直观发现,只有看信令面瀑布图才能定位。
注意:信令面仿真和时间戳记录是云RAN仿真和传统网络仿真最大的区别所在。传统仿真跑完看吞吐就行,但云RAN仿真的核心是看信令交互的时序关系,所以时间戳必须精确到0.1ms,否则后续时延分析完全没法看。
4. 前传和中传的参数配置,最容易“看起来在仿真,实际在造假”的地方
这一节讲讲参数配置,尤其是前传/中传的承载模型。很多仿真项目的问题不是技术选型不对,而是参数拍脑袋拍得离谱,导致整个仿真结果不具备参考意义。云RAN架构仿真里,传输链路的参数化配置是决定结果可信度的关键一环。
4.1 前传说带宽必须按IQ数据算,别按业务数据算
我见过最多的问题就是有人把前传带宽配置成跟中传一样的数值。这在工程上是错的。前传传输的是IQ采样数据,即使采用压缩方案,也比业务数据量大得多。
举个例子,5G小区100MHz带宽、30kHz子载波间隔、128根天线,单天线端口的IQ数据率就按下面的公式估算:
IQ数据率 = 采样率 × 比特深度 × 天线端口数
100MHz带宽下采样率约为122.88MHz,用16bit量化IQ(每采样I和Q各16bit,实际32bit),单端口IQ率就是122.88M × 32bit ≈ 3.93Gbps。如果是单小区少天线端口,前传带宽通常按10Gbps起步配置;如果是Massive MIMO场景,64端口直接奔着上百Gbps去了。
而实际业务数据速率可能只有几百Mbps,差了整整两个数量级。你把前传配置成1Gbps,看起来网络够宽,仿真跑完业务正常,但真实前传早爆了——排队的排队,丢弃的丢弃,端到端时延飙到不可用。这个不是仿真的问题,是“错误参数正确跑完”的问题。
4.2 前传时延和同步误差要按微秒级建模
云RAN的前传对时延是极其苛刻的。3GPP对前传的时延要求通常按微秒级考量,整个RU-DU间的时间同步误差一般在±1.5us量级(基于TSN的Fronthaul场景),这不是毫秒级网络能承载的。
仿真里我是这么处理的:前传链路时延设置成常数加抖动模型,常数设置为100us,抖动按高斯分布,标准差20us。这个抖动模型来源是有讲究的,光纤传输本身很稳定,但中间经过的交换设备和光电转换会产生时延抖动,仿真里不建模这部分,时延敏感业务的性能评估就会失真。
对比一下不同配置的结果:前传时延从100us调到1ms(很多人觉得1ms不高啊),URLLC场景的端到端时延预算立刻超标。因为URLLC通常要求端到端5ms内,前传这一下就吃掉1ms,再加上空口调度、DU处理、核心网传输,剩余预算根本不够。仿真里看得很清楚,毫秒级前传时延直接让URLLC业务的达标率从99.999%掉到96%。这种配置在真实系统里天线、功放、调度根本来不及应变。
4.3 F1接口的中传参数:带宽和时延的折中关系
F1接口承载RLC/PDCP数据,对时延的要求没有前传那么极端,但因为F1往往要跨越较长的传输距离,所以时延的绝对值不小。我在仿真里设置了从0.1ms到2ms的扫参范围,搭配20Gbps带宽,结果发现F1时延对TCP吞吐的敏感度没有想象的那么高,真正敏感的是带CU-UP的集中式部署场景下,用户面数据从DU到CU-UP的路径会变长,TCP的RTT增大,吞吐自然下降。
所以做云RAN架构仿真时,F1的参数配置不能只看时延数字,还要看业务模型。实时性业务(语音、RRC信令、终端SIM卡鉴权)对时延敏感,吞吐型业务(视频下载、文件传输)更关心带宽和丢包。F1建模要在仿真分层时把QoS策略分开,否则最后出的平均时延指标没有参考价值。
5. 时延模型与同步机制,是云RAN仿真里最被低估的一环
我做了几轮云RAN仿真后深刻体会到:时延模型是云RAN仿真软件的精髓,同步机制是被低估最多的细节。这一节展开讲讲这两个点。
5.1 功能切分(Functional Split)影响时延累积效应
云RAN之所以有那么多架构选项,核心就是不同功能切分方案对时延的累积影响差异。仿真里我把常见切分做了一个对比:
| 切分点 | 放RU的功能 | 放DU的功能 | CU处理 | 前传时延要求 | 典型场景 |
|---|---|---|---|---|---|
| Option 8(射频切分) | RF+ADC/DAC | PHY High及以上 | MAC/RLC/PDCP | 极高(us级) | 集中化程度最高,但前传压力巨大 |
| Option 7.2(低PHY切分) | RF+低PHY | 高PHY+MAC+RLC | PDCP | 高(百us级) | 商用主流,兼顾集中化和前传成本 |
| Option 2(RLC切分) | RF+PHY+MAC | RLC以下 | PDCP | 低(ms级) | 分布式较强,集中增益减弱 |
| Option 6(MAC切分) | RF+PHY+MAC | MAC以上 | RLC/PDCP | 低(ms级) | 早期CloudRAN方案,兼容4G演进 |
我在仿真里为了对照,同时配置了Option 7.2和Option 2两种模式。同样的网络拓扑,同样的业务模型,Option 7.2下前传时延必须低于200us才能稳定运行URLLC,而Option 2下整个链路时延预算大幅放宽,前传就算容忍1ms也可以。代价是Option 2的集中化增益有限,DU不可集中部署得太远。这个结论就是通过仿真“跑”出来的,如果只看架构白皮书,很难形成这么直观的判断。
5.2 时间同步协议仿真里的近似处理
云RAN架构里,RU和DU之间的时间同步是基于IEEE 1588 v2(PTP)或增强型CPRI的同步机制的。仿真里要不要做Step-by-step的PTP协议模拟?我一开始觉得要,后来踩了坑发现不需要。
PTP协议本身的交互细节(Sync、Follow_Up、Delay_Req、Delay_Resp这些消息的收发)对业务性能的影响,远小于最终产生的时钟偏差值。所以在网络仿真里,我直接用“初始偏差+同步周期+收敛精度”三个参数来近似模拟。每次同步后,时钟偏差按正态分布重置在±1.5us以内,然后随时间漂移,漂移速率按温补晶振的典型值50ppb设置。
我最早仿真时没有加这个漂移模型,所有节点时间完全对齐,结果前传队列调度性过于理想。加了50ppb漂移模型后,仿真到了中期就出现了一个很现实的现象:RU和DU的时间偏差逐渐累积,跨节点调度时出现了微秒级的时钟窗口重叠,HARQ时序开始抖动。这就是真实系统里小误差导致大故障的典型现象,仿真里还原它反而让结果更可信。
6. 仿真脚本设计:参数生成、事件调度和结果采集的工程实现
到了这一节,先把理论收一收,聊一聊仿真代码怎么设计。我这次用的是Python写的离散事件仿真框架,代码量不算大,但设计中遵循了三条原则。
6.1 参数生成,不要写死在代码里
所有关键参数必须从配置文件读入。前传时延、中传时延、处理时延、带宽、队列长度、业务模型参数、仿真时长、随机种子,全部外置。我做了一个YAML配置文件片段,大概长这样:
simulation: duration_ms: 10000 random_seed: 42 topology: ru_du_fronthaul: delay_us: 100 delay_jitter_us: 20 bitrate_gbps: 10 du_cuup_midhaul: delay_us: 200 bitrate_gbps: 20 cu_cp_processing_ms: 0.8 traffic: urllc: interval_ms: 2 packet_size_bytes: 200 embb: rate_mbps: 100 packet_size_bytes: 1500这样做的原因很朴素:你写死在代码里的参数,后面想扫参必然后悔。我有一次把前传时延写死在代码里,开头跑完才发现要对比三组时延配置,改代码花了半小时,重新跑仿真花了半小时,总共浪费一小时——而这个时间本可以用来分析数据。
6.2 事件调度,优先队列是核心
离散事件仿真的核心就是事件队列。Python里可以用heapq直接实现优先队列,事件按时间戳排序取出。我定义了事件基类:
class Event: def __init__(self, time_ms, event_type, node_id): self.time_ms = time_ms self.event_type = event_type self.node_id = node_id def __lt__(self, other): return self.time_ms < other.time_ms class SimulationEngine: def __init__(self): self.event_queue = [] self.current_time = 0.0 self.statistics = [] def run(self): while self.event_queue: event = heapq.heappop(self.event_queue) self.current_time = event.time_ms self.handle_event(event) def schedule(self, event): heapq.heappush(self.event_queue, event)每个网络节点(RU、DU、CU-CP、CU-UP)都是一个事件处理器,收到事件后根据类型决定如何处理、是否生成新事件、何时生成。我最开始写的时候把事件类型定义得太大(比如一个“数据包到达”事件包含所有细节),导致代码耦合严重。后来改成小事件+细粒度类型,每个节点只处理自己关心的事件,架构会清晰许多。
6.3 结果采集,分场景统计才有价值
仿真跑完,需要输出各个层级的统计量。我输出的维度包括:
- 每段链路的平均时延、P95时延、P99时延。
- DU和CU-CP的处理时延分布。
- F1接口排队长度变化趋势。
- URLLC端到端时延达标率。
- eMBB业务的吞吐量。
特别强调P95和P99,因为均值在云RAN架构仿真里几乎没有意义。前传偶尔一次较大的时延抖动,对均值的影响可能只有几个百分点,但P99可能已经翻了十倍。URLLC业务考量的恰恰是最坏情况,不看P99等于白做。
数据的采集我用的方式是在每个事件处理函数里记录关键事件到一个列表,仿真结束后统一汇总,而不是实时计算。原因很直接:实时计算会拖慢事件循环,而且仿真跑完一次性算出的统计量如果需要调整口径,重新算一遍列表即可,不用重新跑仿真。
7. 部署与验证:仿真跑通不等于仿真可信
仿真代码写完不是终点。这个环节我吃过亏:第一次跑通的时候,看到吞吐指标符合预期,以为完事了,结果一分析时延的P99数据,发现与预期差距极大,但这个差距被平均吞吐掩盖了。所以部署之后必须有一轮“验证仿真可信性”的流程。
7.1 部署形态:单机仿真到分布式仿真的演进
云RAN仿真项目前期单机跑没问题,但节点一多、场景一复杂,CPU会顶不住。我早期做了200个小区、400个DU/CU节点、2000个UE的仿真,单机跑了一个小时都没出来。后面优化成两种方式:
第一种是把仿真进程按节点类型拆分到多进程。DU进程、CU进程、UE进程独立跑事件循环,进程间通过共享队列传输跨节点事件。这个改动不算复杂,但显著减少了单进程压力。
第二种是更彻底的分布式。把仿真拓扑按区域分区,每个分区跑一个Worker进程,主进程负责区域间的事件转发。区域间的事件主要是切换(UE从一个DU区域切到另一个DU区域)和核心网信令交互。
我个人实测下来,单机多进程收益远比分布式明显,因为区域间事件转发的通信开销不小。除非你的项目规模真的到了几十万用户,否则优先优化单进程的事件处理效率。
7.2 结果判据:怎么判断仿真结果“没跑飞”
我每次仿真跑完,先按一套校验流程检查,确认没问题再往下分析:
- 无线空口利用率不超过95%,否则说明调度器参数过于激进,需要重新检查调度算法。
- F1接口平均队列长度不超过阈值,且P95小于队列容量的90%,否则意味着带宽配置明显不足。
- URLLC端到端时延达标率与理论值偏差小于1个百分点。这个偏差如果大了,优先检查前传时延配置是否有常数设置错误。
- 吞吐指标与理论峰值误差在可接受范围内。这里的“理论峰值”可以由香农公式结合带宽和MCS等级估算。
提示:验证阶段直接使用“对照实验”的思路最有效。保持其他参数不变,单独把前传时延从100us改成1ms,URLLC达标率必须出现可观测的下降。如果这两个结果一样,说明你的仿真模型里前传根本没有被真正计算进去——这是我的仿真项目里经常遇到的问题。
8. 踩坑实录:时延指标异常跳变,排查链路的完整过程
讲一个我印象很深的故障排查过程。某一轮仿真跑完,URLLC端到端时延明明应该稳定在4ms左右,结果P95直接跳到22ms,而且完全看不出规律。这个现象持续了三轮随机种子,排除了随机性。排查过程如下。
8.1 第一层排查:先看每一段的时延分布,缩小问题范围
我先把端到端时延按链路分段统计,结果发现前传时延正常(均值104us),中传时延正常(均值205us),唯独CU-UP处理时延出现异常尖峰,某些包的处理时延突然从0.3ms跳到了15ms。
看到这个结果,我第一反应是CU-UP节点的事件处理逻辑出了问题——可能某个事件没有按预期触发,阻塞了队列。于是我去看CU-UP的事件处理代码,排查是否有不可重入的全局变量导致事件处理互锁。
8.2 第二层排查:仿真引擎时间戳的异步问题
查了一轮代码没发现CU-UP逻辑问题,我开始怀疑事件队列的时间戳管理。仔细看事件处理逻辑后,发现我把CU-UP的处理时延写成了“当前仿真时间(Simulation Clock)”的绝对时间差,而不是用事件携带的时间戳。
这意味着:CU-UP处理一个数据包时,如果前一个事件因为特殊原因延后处理,当前事件计算处理时延时会把历史延时也算进去。这个设计缺陷在最开始跑小规模仿真时不会暴露,但一旦业务负载增加、事件并发量上来,前一个事件排队等待的时长就会被错误地累加到下一个包的处理时延里。这就是为什么P95跳变的规律性不强,但持续出现尖峰的根因。
8.3 第三层修复:统一时间戳口径,分离处理延迟与排队延迟
修复方案很简单:CU-UP在处理每个事件时,必须用“事件携带的到达时间戳”作为基准来计算处理时延,不直接使用全局仿真时钟。同时,把每个数据包经历的处理延迟和排队延迟分开记录,防止再次混在一起。
修复后重跑,结果如下:
| 统计项 | 修复前 | 修复后 |
|---|---|---|
| CU-UP平均处理时延 | 0.7ms(均值被尖峰拉高) | 0.31ms |
| URLLC端到端P95 | 22ms | 4.6ms |
| URLLC达标率(5ms预算) | 92% | 99.6% |
这个排查过程给我最大的启发是:在云RAN架构仿真中,分层统计是定位问题的最快路径,时间戳口径的统一是写仿真代码的底线工程。如果一开始就规定所有事件必须携带全局唯一且基于源节点生成的时间戳,这个坑完全可以避免。
9. 仿真迭代优化的几条实操经验
最后聊几条我在这套仿真里积累的经验。这些经验不来自任何教材,都是多次跑仿真、出问题、修复、再跑后沉淀下来的。
第一,仿真参数和结果必须做版本管理。我每一轮跑完会把YAML配置文件、随机种子、结果统计、版本备注一并归档。没有这个习惯,很容易出现“上一版还能复现,加了新需求后结果对不上,但不知道改了什么”的困境。我做了一个简单的文件夹按日期命名,里面放一份配置文件、一份结果输出、一份备注,用树状结构管理起来,后面复盘时会非常省事。
第二,随机种子不能只有一组。同一组参数至少跑3个不同随机种子,取平均值和波动范围,才能判断结果的稳定性。否则一组参数碰上一个极端随机种子,结果差异巨大,完全误导决策。
第三,尽量复用标准化的业务模型。URLLC业务的包大小、到达间隔、时延预算门槛,eMBB业务的下载速率、会话时长,这些模型在不同项目里几乎不变,应该整理成一份公共库,避免每次新项目都要重新定义一遍。仿真模型的一致性直接影响到不同轮次结果的可比性。
第四,云RAN架构里CU-CP和CU-UP的处理时延不能拍脑袋设同一个值。我实测下来,控制面的RRC处理时延通常远大于用户面的PDCP处理时延,因为RRC决策涉及上下文管理、测量配置、安全算法,计算复杂度高。用户面处理相对机械。我把CU-CP设成0.8ms、CU-UP设成0.3ms,接近真实系统的处理时延比例,仿真结果与现场实测的吻合度明显更好。
第五,如果你做的是真实场景的5G网络仿真,而不仅仅是一般性的无线网络仿真,建议仿真完成后找现场的信令跟踪数据做对照。我有一次用真实前传时延分布替换了仿真里的高斯分布,结果URLLC达标率从99.6%掉到了98.1%。原因很直接:真实网络中的时延分布往往是偏态分布,高斯分布过于理想化。虽然这个过程增加了一轮调参,但换来了比理论评估高得多的可信度。
关于云RAN架构的仿真,我能分享的核心就是把架构拆得足够清楚,把每一段的时延、带宽、处理能力都变成可配置参数,然后让数据说话。仿真模型的作用不是逼真到和真实协议栈一样,而是把架构决策的物理本质和网络本质用可量化的方式呈现出来,让每一个方案选择都有依据。这套思路不论你用什么工具做5G网络仿真,应该都能适用。