主题066:边缘计算与仿真

目录

  1. 引言
  2. 边缘计算基础理论
  3. 边缘计算架构
  4. 任务卸载与调度算法
  5. 边缘-云协同计算
  6. 5G与实时仿真应用
  7. 完整代码实现
  8. 代码深度解析
  9. 运行结果分析
  10. 进阶挑战
  11. 总结与习题
  12. 参考资料

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

引言

1.1 什么是边缘计算?

边缘计算(Edge Computing)是一种分布式计算范式,它将计算和数据存储资源从传统的集中式云端推向网络边缘,靠近数据源和终端用户。这一概念源于物联网(IoT)的快速发展,以及对低延迟、高带宽、实时处理能力的迫切需求。

在传统的云计算架构中,所有数据都需要传输到远程数据中心进行处理,这导致了显著的延迟。对于许多实时应用,如自动驾驶、工业控制、远程医疗等,这种延迟是不可接受的。边缘计算通过在数据源附近部署计算节点,将处理任务下沉到网络边缘,从而大幅降低响应时间。

1.2 边缘计算在工程仿真中的意义

工程仿真领域对计算资源的需求日益增长,从简单的热传导分析到复杂的多物理场耦合仿真,计算复杂度呈指数级增长。边缘计算为工程仿真带来了革命性的变化:

1. 实时仿真能力

  • 传统仿真往往需要数小时甚至数天才能完成
  • 边缘计算使得实时或近实时的仿真成为可能
  • 支持数字孪生(Digital Twin)等新兴应用

2. 分布式协同仿真

  • 大型复杂系统可以分解为多个子系统
  • 各子系统在边缘节点并行计算
  • 通过协同机制实现整体系统仿真

3. 数据本地化处理

  • 工业现场的传感器数据无需全部上传云端
  • 在边缘进行预处理和初步分析
  • 仅将关键结果传输到云端

4. 降低带宽成本

  • 减少核心网络的数据传输量
  • 缓解云端计算压力
  • 提高整体系统效率

1.3 学习目标

完成本主题学习后,你将能够:

  1. 理解边缘计算的核心概念:包括边缘节点、雾计算、任务卸载等关键技术
  2. 掌握边缘-云协同架构:了解如何设计高效的边缘-云协同系统
  3. 实现任务调度算法:编写代码实现任务卸载和资源调度策略
  4. 应用5G技术:理解5G网络如何赋能实时仿真应用
  5. 解决实际问题:将边缘计算应用于工程仿真场景

1.4 应用场景

边缘计算在工程仿真领域的典型应用场景包括:

应用场景 延迟要求 计算需求 边缘计算优势
智能制造监控 < 10ms 中等 实时质量控制
自动驾驶仿真 < 1ms 安全关键决策
风电场监测 < 100ms 低-中 预测性维护
建筑结构健康监测 < 50ms 实时安全评估
AR/VR辅助设计 < 20ms 沉浸式体验

边缘计算基础理论

2.1 边缘计算的定义与特点

2.1.1 核心定义

边缘计算是指在靠近物或数据源头的网络边缘侧,融合网络、计算、存储、应用核心能力的开放平台,就近提供边缘智能服务,满足行业数字化在敏捷连接、实时业务、数据优化、应用智能、安全与隐私保护等方面的关键需求。

2.1.2 关键特点

1. 低延迟(Low Latency)

边缘计算最显著的优势是极低的网络延迟。由于计算任务在数据源附近执行,避免了数据长距离传输带来的延迟。典型的边缘节点延迟在1-10毫秒,而传统云计算的延迟通常在50-200毫秒。

2. 带宽优化(Bandwidth Optimization)

通过在边缘进行数据预处理和过滤,可以显著减少需要传输到云端的数据量。例如,在视频监控场景中,边缘节点可以只将异常事件的相关数据传输到云端,而不是持续上传所有视频流。

3. 数据隐私与安全(Privacy and Security)

敏感数据可以在本地处理,无需上传到云端,从而降低了数据泄露的风险。这对于医疗、金融等对数据隐私要求极高的行业尤为重要。

4. 可靠性(Reliability)

即使与云端的网络连接中断,边缘节点仍能独立运行,保证关键业务的连续性。这种离线工作能力在工业控制等场景中至关重要。

5. 可扩展性(Scalability)

边缘计算架构支持分布式部署,可以根据需求灵活增加边缘节点,实现系统的水平扩展。

2.2 边缘计算与云计算的关系

边缘计算并非要取代云计算,而是与之形成互补关系。理解两者的关系对于设计高效的计算架构至关重要。

2.2.1 云计算的优势与局限

优势:

  • 几乎无限的计算和存储资源
  • 成熟的服务生态系统
  • 集中管理和维护
  • 成本效益(按需付费)

局限:

  • 高延迟(50-200ms)
  • 带宽瓶颈
  • 数据隐私风险
  • 依赖网络连接
2.2.2 边缘计算的优势与局限

优势:

  • 极低延迟(1-10ms)
  • 减少带宽消耗
  • 数据本地化处理
  • 离线工作能力

局限:

  • 计算资源有限
  • 管理和维护复杂
  • 部署成本高
  • 安全性挑战
2.2.3 边缘-云协同

最佳的解决方案是边缘计算与云计算的协同工作:

┌─────────────────────────────────────────────────────────────┐
│                        云端 (Cloud)                          │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────────┐  │
│  │ 大数据分析   │  │ 模型训练    │  │ 全局优化与决策       │  │
│  │ 历史数据存储 │  │ AI/ML服务   │  │ 集中管理与监控       │  │
│  └─────────────┘  └─────────────┘  └─────────────────────┘  │
└─────────────────────────────────────────────────────────────┘
                              ↑
                              │ 聚合数据、模型更新
                              ↓
┌─────────────────────────────────────────────────────────────┐
│                      雾层 (Fog Layer)                        │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────────┐  │
│  │ 区域聚合    │  │ 数据预处理  │  │ 中间层分析          │  │
│  │ 负载均衡    │  │ 协议转换    │  │ 边缘节点管理        │  │
│  └─────────────┘  └─────────────┘  └─────────────────────┘  │
└─────────────────────────────────────────────────────────────┘
                              ↑
                              │ 局部数据、控制指令
                              ↓
┌─────────────────────────────────────────────────────────────┐
│                      边缘层 (Edge Layer)                     │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────────┐   │
│  │ 边缘节点1 │ │ 边缘节点2 │ │ 边缘节点3 │ │   ...        │   │
│  │ 实时处理  │ │ 实时处理  │ │ 实时处理  │ │              │   │
│  │ 数据采集  │ │ 数据采集  │ │ 数据采集  │ │              │   │
│  └──────────┘ └──────────┘ └──────────┘ └──────────────┘   │
└─────────────────────────────────────────────────────────────┘
                              ↑
                              │ 原始数据、传感器输入
                              ↓
┌─────────────────────────────────────────────────────────────┐
│                      设备层 (Device Layer)                   │
│     传感器        执行器        智能终端       工业设备       │
└─────────────────────────────────────────────────────────────┘

2.3 边缘计算的关键技术

2.3.1 虚拟化与容器化

边缘节点资源有限,需要轻量级的虚拟化技术:

容器技术(Docker):

  • 轻量级,启动速度快(秒级)
  • 资源占用少
  • 便于应用部署和迁移
  • 支持微服务架构

轻量级虚拟机:

  • 如 Kata Containers、gVisor
  • 提供更强的隔离性
  • 适用于多租户场景
2.3.2 任务卸载(Task Offloading)

任务卸载是边缘计算的核心技术,决定哪些任务在边缘执行,哪些任务卸载到云端。

卸载决策考虑因素:

  1. 任务特性:计算复杂度、数据量、实时性要求
  2. 网络状况:带宽、延迟、稳定性
  3. 资源状态:边缘节点负载、可用计算能力
  4. 能耗约束:电池供电设备的能耗限制
  5. 成本因素:计算成本、传输成本

卸载策略类型:

  • 完全本地执行:所有任务在边缘处理
  • 完全卸载:所有任务发送到云端
  • 部分卸载:任务分割,部分在边缘、部分在云端
  • 协作执行:边缘和云端协同完成任务
2.3.3 边缘智能(Edge Intelligence)

将人工智能能力下沉到边缘:

模型优化技术:

  • 模型压缩(剪枝、量化)
  • 知识蒸馏
  • 神经网络架构搜索(NAS)

联邦学习(Federated Learning):

  • 数据不离开本地
  • 分布式模型训练
  • 保护数据隐私

边缘计算架构

3.1 三层架构模型

边缘计算系统通常采用三层架构:

3.1.1 云端层(Cloud Layer)

云端层提供全局管理和资源调度功能:

核心功能:

  • 全局资源管理
  • 大数据分析
  • 模型训练与更新
  • 集中监控与运维
  • 长期数据存储

在仿真中的应用:

  • 复杂仿真模型的训练
  • 历史仿真数据的分析
  • 全局优化算法执行
  • 仿真结果的可视化展示
3.1.2 雾层/边缘层(Fog/Edge Layer)

雾层作为中间层,连接云端和边缘节点:

核心功能:

  • 区域数据聚合
  • 负载均衡
  • 边缘节点管理
  • 数据预处理
  • 本地决策

在仿真中的应用:

  • 子系统仿真协调
  • 数据预处理与过滤
  • 局部优化
  • 实时结果汇总
3.1.3 设备层(Device Layer)

设备层包括各种终端设备和传感器:

核心功能:

  • 数据采集
  • 简单预处理
  • 指令执行
  • 状态监测

在仿真中的应用:

  • 物理量测量(温度、应力、位移等)
  • 仿真边界条件获取
  • 结果验证数据收集

3.2 边缘节点类型

根据功能和位置,边缘节点可以分为以下几类:

3.2.1 边缘服务器(Edge Server)

部署在基站、接入点等位置的计算服务器:

特点:

  • 计算能力较强(多核CPU、GPU)
  • 存储容量大
  • 网络带宽高
  • 可运行复杂应用

典型配置:

  • CPU:16-64核心
  • 内存:32-256GB
  • 存储:TB级SSD
  • 网络:10Gbps+
3.2.2 微边缘节点(Micro Edge)

部署在设备附近的小型计算单元:

特点:

  • 体积小、功耗低
  • 计算能力有限
  • 实时响应快
  • 成本低廉

典型配置:

  • CPU:ARM架构,4-8核心
  • 内存:2-8GB
  • 存储:GB级eMMC
  • 网络:WiFi/4G/5G
3.2.3 智能网关(Smart Gateway)

连接设备和边缘网络的枢纽:

特点:

  • 协议转换能力
  • 数据聚合
  • 边缘计算能力
  • 安全防护

典型应用:

  • 工业网关
  • 智能家居中枢
  • 车载计算单元

3.3 网络拓扑设计

边缘计算系统的网络拓扑直接影响系统性能和可靠性。

3.3.1 星型拓扑

所有边缘节点直接连接到中心节点:

         ┌─────────┐
         │  云端   │
         └────┬────┘
              │
         ┌────┴────┐
         │  网关   │
         └────┬────┘
              │
    ┌────┬────┼────┬────┐
    ↓    ↓    ↓    ↓    ↓
  ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐
  │E1│ │E2│ │E3│ │E4│ │E5│
  └──┘ └──┘ └──┘ └──┘ └──┘

优点:

  • 结构简单,易于管理
  • 故障隔离性好

缺点:

  • 单点故障风险
  • 网关压力大
3.3.2 网状拓扑

边缘节点之间相互连接:

       ┌─────────┐
       │  云端   │
       └────┬────┘
            │
    ┌───────┼───────┐
    │       │       │
  ┌─┴─┐   ┌─┴─┐   ┌─┴─┐
  │E1 │───│E2 │───│E3 │
  └───┘   └───┘   └───┘
    │       │       │
  ┌─┴─┐   ┌─┴─┐   ┌─┴─┐
  │E4 │───│E5 │───│E6 │
  └───┘   └───┘   └───┘

优点:

  • 高可靠性
  • 负载可以分散
  • 支持P2P通信

缺点:

  • 管理复杂
  • 路由开销大
3.3.3 层次拓扑

多层级的树状结构:

              ┌─────────┐
              │  云端   │
              └────┬────┘
                   │
           ┌───────┴───────┐
           │     雾节点    │
           └───────┬───────┘
           ┌───────┼───────┐
           ↓       ↓       ↓
      ┌────┴┐  ┌───┴──┐  ┌┴────┐
      │区域1│  │区域2 │  │区域3│
      └──┬──┘  └───┬──┘  └──┬──┘
    ┌────┼────┐   │   ┌────┼────┐
    ↓    ↓    ↓   ↓   ↓    ↓    ↓
  ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐
  │E1│ │E2│ │E3│ │E4│ │E5│ │E6│ │E7│
  └──┘ └──┘ └──┘ └──┘ └──┘ └──┘ └──┘

优点:

  • 可扩展性好
  • 适合大规模部署
  • 层次化管理

缺点:

  • 延迟可能增加
  • 需要精心设计层次

任务卸载与调度算法

4.1 任务卸载问题建模

任务卸载问题的核心是决策:对于每个到达的任务,决定在哪里执行(本地边缘节点、其他边缘节点、云端)。

4.1.1 系统模型

任务模型:
每个任务可以表示为一个元组:
T i = ( D i , C i , τ i , p i ) T_i = (D_i, C_i, \tau_i, p_i) Ti=(Di,Ci,τi,pi)

其中:

  • D i D_i Di:数据量(MB)
  • C i C_i Ci:计算需求(GFLOPS)
  • τ i \tau_i τi:截止时间(ms)
  • p i p_i pi:优先级

节点模型:
每个边缘节点可以表示为:
N j = ( f j , M j , B j , L j ) N_j = (f_j, M_j, B_j, L_j) Nj=(fj,Mj,Bj,Lj)

其中:

  • f j f_j fj:CPU频率(GHz)
  • M j M_j Mj:内存容量(GB)
  • B j B_j Bj:网络带宽(Mbps)
  • L j L_j Lj:基础延迟(ms)
4.1.2 延迟模型

本地执行延迟:
T l o c a l = C i f j × n j × 1000 + L j p r o c T_{local} = \frac{C_i}{f_j \times n_j} \times 1000 + L_j^{proc} Tlocal=fj×njCi×1000+Ljproc

其中 n j n_j nj 是CPU核心数, L j p r o c L_j^{proc} Ljproc 是处理延迟。

卸载到云端延迟:
T c l o u d = L j u p + D i × 8 B j u p × 1000 + C i f c l o u d × 1000 + L c l o u d d o w n + D i r e s u l t × 8 B j d o w n × 1000 T_{cloud} = L_j^{up} + \frac{D_i \times 8}{B_j^{up}} \times 1000 + \frac{C_i}{f_{cloud}} \times 1000 + L_{cloud}^{down} + \frac{D_i^{result} \times 8}{B_j^{down}} \times 1000 Tcloud=Ljup+BjupDi×8×1000+fcloudCi×1000+Lclouddown+BjdownDiresult×8×1000

其中:

  • L j u p L_j^{up} Ljup:上传基础延迟
  • B j u p B_j^{up} Bjup:上传带宽
  • f c l o u d f_{cloud} fcloud:云端计算能力
  • D i r e s u l t D_i^{result} Diresult:结果数据量

4.2 卸载决策算法

4.2.1 贪心算法

最简单的卸载策略是贪心算法:对于每个任务,选择延迟最小的执行位置。

算法步骤:

  1. 计算任务在所有可选节点的执行延迟
  2. 选择延迟最小的节点
  3. 如果该节点资源不足,选择次优节点

优点:

  • 实现简单
  • 计算开销小
  • 适合实时决策

缺点:

  • 可能不是全局最优
  • 容易导致某些节点过载
4.2.2 基于阈值的卸载

设定延迟阈值,根据阈值决定卸载策略:

if T_local <= threshold:
    execute_locally()
elif T_cloud < T_local:
    offload_to_cloud()
else:
    execute_locally()  # 即使超过阈值,云端也不更优

阈值选择:

  • 可以根据应用需求设定
  • 可以动态调整
  • 可以基于历史数据学习
4.2.3 基于机器学习的卸载

使用机器学习模型预测最优卸载决策:

特征工程:

  • 任务特征:数据量、计算需求、优先级
  • 网络特征:当前带宽、延迟、丢包率
  • 节点特征:负载、可用资源
  • 历史特征:过去决策的效果

模型选择:

  • 决策树:可解释性强
  • 神经网络:精度高
  • 强化学习:可以在线学习优化

4.3 资源调度算法

4.3.1 先来先服务(FCFS)

最简单的调度策略,按任务到达顺序执行。

优点:

  • 实现简单
  • 公平性好

缺点:

  • 不考虑任务优先级
  • 长任务会阻塞短任务
4.3.2 最短作业优先(SJF)

优先执行预计执行时间最短的任务。

优点:

  • 平均等待时间短
  • 系统吞吐率高

缺点:

  • 需要预知执行时间
  • 长任务可能饿死
4.3.3 优先级调度

根据任务优先级进行调度。

优先级考虑因素:

  • 任务紧急程度
  • 任务价值
  • 截止时间
  • 资源需求

改进策略:

  • 动态优先级:随等待时间增加而提升
  • 多级反馈队列:不同优先级使用不同队列
4.3.4 负载均衡调度

将任务分配到负载最轻的节点。

负载指标:

  • CPU利用率
  • 内存使用率
  • 网络带宽占用
  • 任务队列长度

调度策略:

  • 轮询(Round Robin)
  • 最少连接(Least Connections)
  • 加权最小响应时间

边缘-云协同计算

5.1 协同计算模式

5.1.1 数据协同

边缘负责数据采集和预处理,云端负责深度分析:

设备层 → 边缘层(过滤/聚合)→ 云端层(分析/存储)
   ↑                                    ↓
   └──────────── 控制指令 ←─────────────┘

协同流程:

  1. 边缘节点采集原始数据
  2. 进行初步处理和过滤
  3. 提取特征,压缩数据
  4. 上传关键数据到云端
  5. 云端进行深度分析
  6. 将分析结果下发到边缘
5.1.2 计算协同

复杂任务分解为子任务,在边缘和云端并行执行:

任务分解策略:

  • 数据并行:将数据分割,在不同节点并行处理
  • 模型并行:将模型分割,不同节点负责不同部分
  • 流水线:任务分解为多个阶段,形成流水线

协同示例(热仿真):

┌─────────────────────────────────────────────────────┐
│                    热仿真任务                        │
└──────────────────┬──────────────────────────────────┘
                   │
       ┌───────────┼───────────┐
       ↓           ↓           ↓
  ┌─────────┐ ┌─────────┐ ┌─────────┐
  │边界条件 │ │网格生成 │ │材料属性 │
  │  处理   │ │         │ │  查询   │
  └────┬────┘ └────┬────┘ └────┬────┘
       │           │           │
       └───────────┼───────────┘
                   ↓
            ┌─────────────┐
            │  求解器计算  │ ← 可以在边缘或云端
            └──────┬──────┘
                   ↓
            ┌─────────────┐
            │  结果后处理  │ ← 通常在边缘(可视化)
            └─────────────┘
5.1.3 模型协同

边缘使用轻量级模型进行实时推理,云端使用复杂模型进行精确分析:

模型协同策略:

  1. 模型分割:将神经网络分割为边缘部分和云端部分
  2. 模型压缩:边缘使用压缩模型,云端使用完整模型
  3. 结果融合:结合边缘快速结果和云端精确结果

5.2 协同优化目标

边缘-云协同系统需要平衡多个优化目标:

5.2.1 延迟优化

最小化任务完成时间:
min ⁡ ∑ i T i c o m p l e t e \min \sum_{i} T_i^{complete} miniTicomplete

优化策略:

  • 优先在边缘处理实时性要求高的任务
  • 使用预测性调度
  • 预加载常用数据和模型
5.2.2 能耗优化

最小化系统总能耗:
min ⁡ ( E e d g e + E c l o u d + E n e t w o r k ) \min (E_{edge} + E_{cloud} + E_{network}) min(Eedge+Ecloud+Enetwork)

优化策略:

  • 动态调整节点功率状态
  • 优化数据传输
  • 使用能效高的节点
5.2.3 成本优化

最小化运营成本:
min ⁡ ( C c o m p u t e + C s t o r a g e + C n e t w o r k + C m a i n t e n a n c e ) \min (C_{compute} + C_{storage} + C_{network} + C_{maintenance}) min(Ccompute+Cstorage+Cnetwork+Cmaintenance)

成本因素:

  • 边缘节点部署和维护成本
  • 云端计算和存储费用
  • 网络带宽费用
  • 人力成本
5.2.4 多目标优化

实际系统需要同时考虑多个目标,可以使用加权求和或帕累托优化:

min ⁡ ( α ⋅ T + β ⋅ E + γ ⋅ C ) \min (\alpha \cdot T + \beta \cdot E + \gamma \cdot C) min(αT+βE+γC)

其中 α \alpha α, β \beta β, γ \gamma γ 是权重系数。

5.3 协同挑战与解决方案

5.3.1 一致性挑战

边缘和云端数据可能不一致。

解决方案:

  • 使用分布式一致性协议
  • 数据版本控制
  • 冲突检测和解决机制
5.3.2 安全挑战

边缘节点数量多、分布广,安全管理困难。

解决方案:

  • 零信任安全架构
  • 边缘安全网关
  • 安全容器和微隔离
  • 定期安全审计
5.3.3 管理挑战

大规模边缘节点的管理和运维复杂。

解决方案:

  • 自动化部署和配置
  • 集中监控和告警
  • 远程诊断和维护
  • 容器编排(如K3s)

5G与实时仿真应用

6.1 5G技术概述

5G(第五代移动通信技术)为边缘计算提供了强大的网络支撑。

6.1.1 5G关键特性
特性 4G 5G 提升
峰值速率 1 Gbps 20 Gbps 20x
用户体验速率 10 Mbps 100 Mbps 10x
空口延迟 10 ms 1 ms 10x
连接密度 10^5/km² 10^6/km² 10x
移动性 350 km/h 500 km/h 1.4x
6.1.2 5G网络架构

5G采用服务化架构(SBA),支持网络切片:

┌─────────────────────────────────────────────────────┐
│                   5G核心网 (5GC)                     │
│  ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐   │
│  │   AMF   │ │   SMF   │ │   UPF   │ │   PCF   │   │
│  │接入管理 │ │会话管理 │ │用户面   │ │策略控制 │   │
│  └─────────┘ └─────────┘ └─────────┘ └─────────┘   │
└─────────────────────────────────────────────────────┘
                          │
                          ↓
┌─────────────────────────────────────────────────────┐
│                   5G接入网 (RAN)                     │
│  ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐   │
│  │  gNB 1  │ │  gNB 2  │ │  gNB 3  │ │   ...   │   │
│  │ 基站    │ │ 基站    │ │ 基站    │ │         │   │
│  └─────────┘ └─────────┘ └─────────┘ └─────────┘   │
└─────────────────────────────────────────────────────┘

关键组件:

  • AMF(Access and Mobility Management Function):接入和移动性管理
  • SMF(Session Management Function):会话管理
  • UPF(User Plane Function):用户面功能,支持边缘计算
  • PCF(Policy Control Function):策略控制
6.1.3 5G与边缘计算的融合

5G网络原生支持边缘计算:

MEC(Multi-access Edge Computing):

  • 将计算能力下沉到基站
  • 支持超低延迟应用
  • 实现本地数据分流

网络切片:

  • 为不同应用创建虚拟专用网络
  • 仿真应用可以获得专用的网络资源
  • 保证服务质量(QoS)

6.2 5G赋能的实时仿真应用

6.2.1 自动驾驶仿真

应用场景:

  • 车辆动力学实时仿真
  • 传感器融合与感知
  • 路径规划与决策
  • V2X通信仿真

延迟要求:

  • 感知:10-20 ms
  • 决策:1-10 ms
  • 控制:< 1 ms

5G优势:

  • 超低延迟支持实时控制
  • 高可靠通信(99.999%)
  • 支持高速移动场景
6.2.2 工业数字孪生

应用场景:

  • 生产线实时监控
  • 设备状态仿真
  • 预测性维护
  • 工艺优化

延迟要求:

  • 监控:50-100 ms
  • 控制:10-20 ms
  • 紧急停机:< 5 ms

5G优势:

  • 支持海量设备连接
  • 确定性延迟
  • 时间敏感网络(TSN)
6.2.3 AR/VR辅助设计

应用场景:

  • 沉浸式产品展示
  • 协同设计评审
  • 远程专家指导
  • 虚拟装配仿真

延迟要求:

  • 头部追踪:< 20 ms
  • 手势识别:< 50 ms
  • 图像渲染:< 16 ms(60fps)

5G优势:

  • 高带宽支持高清视频
  • 边缘渲染降低终端负担
  • 支持移动AR/VR
6.2.4 远程医疗仿真

应用场景:

  • 手术机器人控制
  • 医学影像实时处理
  • 远程诊断
  • 医学培训仿真

延迟要求:

  • 手术控制:< 10 ms
  • 影像传输:< 50 ms
  • 诊断响应:< 100 ms

5G优势:

  • 超低延迟保障手术安全
  • 高可靠传输关键数据
  • 支持高清视频会诊

6.3 实时仿真技术挑战

6.3.1 时间同步

分布式仿真系统需要精确的时间同步。

同步要求:

  • 工业控制:微秒级
  • 自动驾驶:毫秒级
  • 一般仿真:10毫秒级

同步技术:

  • GPS/北斗授时
  • IEEE 1588 PTP(精确时间协议)
  • 5G网络授时
6.3.2 确定性执行

实时仿真需要确定性的执行时间。

实现方法:

  • 实时操作系统(RTOS)
  • 优先级调度
  • 资源预留
  • 时间触发架构
6.3.3 容错与恢复

实时系统需要高可靠性。

容错策略:

  • 冗余设计
  • 快速故障检测
  • 自动故障切换
  • 状态保存与恢复

完整代码实现

以下是边缘计算仿真平台的完整Python实现,包含三个主要示例:

  1. 边缘计算仿真架构:展示边缘节点管理、任务调度和网络拓扑
  2. 边缘-云协同策略对比:对比不同协同策略的性能
  3. 5G实时仿真应用:模拟5G环境下的实时仿真场景
"""
主题066_边缘计算与仿真 - 实例一:边缘计算仿真架构

本代码实现边缘计算仿真平台的核心架构,包括:
1. 边缘节点管理与资源调度
2. 任务卸载决策算法
3. 边缘-云协同计算
4. 低延迟实时仿真
5. 网络拓扑可视化

作者: 仿真教学团队
"""

import matplotlib
matplotlib.use('Agg')  # 使用无头后端,不显示GUI窗口

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Circle, FancyBboxPatch, Arrow, FancyArrowPatch
from matplotlib.collections import LineCollection
import matplotlib.animation as animation
from PIL import Image
import io
import random
from dataclasses import dataclass, field
from typing import List, Dict, Tuple, Optional
from enum import Enum
import time

# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei', 'DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False


class TaskType(Enum):
    """任务类型枚举"""
    THERMAL_SIMULATION = "thermal"      # 热仿真
    STRUCTURAL_SIMULATION = "structural" # 结构仿真
    COUPLED_SIMULATION = "coupled"       # 耦合仿真
    REAL_TIME_MONITOR = "monitor"        # 实时监控
    DATA_PREPROCESS = "preprocess"       # 数据预处理


class NodeType(Enum):
    """节点类型枚举"""
    EDGE = "edge"           # 边缘节点
    FOG = "fog"             # 雾计算节点
    CLOUD = "cloud"         # 云端节点
    GATEWAY = "gateway"     # 网关节点


@dataclass
class SimulationTask:
    """
    仿真任务类
    
    属性:
        task_id: 任务唯一标识
        task_type: 任务类型
        data_size: 数据量 (MB)
        compute_demand: 计算需求 (GFLOPS)
        deadline: 截止时间 (ms)
        priority: 优先级 (1-10)
        arrival_time: 到达时间
        start_time: 开始执行时间
        completion_time: 完成时间
        assigned_node: 分配的节点ID
    """
    task_id: str
    task_type: TaskType
    data_size: float        # 数据量 (MB)
    compute_demand: float   # 计算需求 (GFLOPS)
    deadline: float         # 截止时间 (ms)
    priority: int = 1       # 优先级 (1-10)
    
    # 运行时状态
    arrival_time: float = 0.0
    start_time: Optional[float] = None
    completion_time: Optional[float] = None
    assigned_node: Optional[str] = None
    
    def get_latency(self) -> float:
        """获取任务延迟"""
        if self.completion_time is None:
            return float('inf')
        return self.completion_time - self.arrival_time
    
    def is_meet_deadline(self) -> bool:
        """检查是否满足截止时间"""
        return self.get_latency() <= self.deadline


@dataclass
class EdgeNode:
    """
    边缘计算节点类
    
    属性:
        node_id: 节点唯一标识
        node_type: 节点类型
        position: 地理位置 (x, y)
        cpu_cores: CPU核心数
        cpu_frequency: CPU频率 (GHz)
        memory_gb: 内存 (GB)
        bandwidth_mbps: 带宽 (Mbps)
        latency_ms: 基础延迟 (ms)
        active_tasks: 活跃任务列表
        completed_tasks: 已完成任务列表
        is_active: 节点状态
    """
    node_id: str
    node_type: NodeType
    position: Tuple[float, float]  # 地理位置 (x, y)
    
    # 计算资源
    cpu_cores: int
    cpu_frequency: float    # CPU频率 (GHz)
    memory_gb: float        # 内存 (GB)
    
    # 网络资源
    bandwidth_mbps: float   # 带宽 (Mbps)
    latency_ms: float       # 基础延迟 (ms)
    
    # 状态
    active_tasks: List[SimulationTask] = field(default_factory=list)
    completed_tasks: List[SimulationTask] = field(default_factory=list)
    is_active: bool = True
    
    # 能耗参数
    idle_power: float = 10.0    # 空闲功耗 (W)
    active_power: float = 50.0  # 活跃功耗 (W)
    
    def get_available_compute(self) -> float:
        """
        获取可用计算能力 (GFLOPS)
        
        计算逻辑:
        1. 计算节点总计算能力 = CPU核心数 × CPU频率
        2. 减去活跃任务占用的计算能力
        3. 返回剩余可用计算能力
        """
        used = sum(t.compute_demand for t in self.active_tasks)
        total = self.cpu_cores * self.cpu_frequency
        return max(0, total - used)
    
    def can_accept(self, task: SimulationTask) -> bool:
        """
        检查是否可以接受任务
        
        判断标准:
        - 可用计算能力 >= 任务计算需求的10%
        - 这样可以确保任务能够被执行
        """
        return self.get_available_compute() >= task.compute_demand * 0.1
    
    def estimate_completion_time(self, task: SimulationTask) -> float:
        """
        估计任务完成时间 (ms)
        
        计算组成:
        1. 基础延迟: 网络传输延迟
        2. 传输时间: 数据量 / 带宽
        3. 计算时间: 计算需求 / 可用计算能力
        
        公式: T_total = T_latency + T_transmission + T_computation
        """
        if not self.can_accept(task):
            return float('inf')
        
        # 计算时间 = 计算需求 / 可用计算能力
        compute_time = task.compute_demand / self.get_available_compute() * 1000
        
        # 传输时间 = 数据量 / 带宽
        transmission_time = task.data_size * 8 / self.bandwidth_mbps * 1000
        
        return self.latency_ms + transmission_time + compute_time
    
    def assign_task(self, task: SimulationTask, current_time: float):
        """分配任务到节点"""
        task.start_time = current_time
        task.assigned_node = self.node_id
        self.active_tasks.append(task)
    
    def process_tasks(self, current_time: float, time_step: float):
        """
        处理活跃任务
        
        处理逻辑:
        1. 计算每个任务在当前时间步的进度
        2. 如果任务完成,移动到已完成列表
        3. 返回已完成的任务列表
        """
        completed = []
        for task in self.active_tasks[:]:
            # 简化模型:假设任务按时间步推进
            progress = time_step / (task.compute_demand / 
                                   (self.cpu_cores * self.cpu_frequency) * 1000)
            
            if progress >= 1.0 or random.random() < progress:
                task.completion_time = current_time
                self.completed_tasks.append(task)
                self.active_tasks.remove(task)
                completed.append(task)
        
        return completed
    
    def get_power_consumption(self) -> float:
        """
        获取当前功耗
        
        计算逻辑:
        - 空闲状态: 返回空闲功耗
        - 活跃状态: 根据负载计算功耗
          功耗 = 空闲功耗 + (活跃功耗 - 空闲功耗) × 负载因子
        """
        if len(self.active_tasks) > 0:
            load_factor = min(1.0, len(self.active_tasks) / self.cpu_cores)
            return self.idle_power + (self.active_power - self.idle_power) * load_factor
        return self.idle_power


class EdgeComputingPlatform:
    """
    边缘计算平台主类
    
    职责:
    1. 管理边缘节点池
    2. 协调任务调度
    3. 提供平台级统计信息
    4. 支持任务卸载决策
    """
    
    def __init__(self):
        """初始化边缘计算平台"""
        self.edge_nodes: Dict[str, EdgeNode] = {}
        self.cloud_node: Optional[EdgeNode] = None
        self.gateway_nodes: List[EdgeNode] = []
        
        # 网络拓扑
        self.connections: List[Tuple[str, str, float]] = []  # (node1, node2, latency)
        
        # 任务队列
        self.pending_tasks: List[SimulationTask] = []
        self.all_tasks: List[SimulationTask] = []
        
        # 时间
        self.current_time = 0.0
        
        # 统计
        self.stats_history = []
        
        print("="*60)
        print("边缘计算仿真平台初始化")
        print("="*60)
    
    def add_edge_node(self, node: EdgeNode):
        """添加边缘节点"""
        self.edge_nodes[node.node_id] = node
        print(f"添加边缘节点: {node.node_id} @ ({node.position[0]:.1f}, {node.position[1]:.1f})")
    
    def set_cloud_node(self, node: EdgeNode):
        """设置云端节点"""
        self.cloud_node = node
        print(f"设置云端节点: {node.node_id}")
    
    def add_gateway(self, node: EdgeNode):
        """添加网关节点"""
        self.gateway_nodes.append(node)
        print(f"添加网关: {node.node_id}")
    
    def add_connection(self, node1_id: str, node2_id: str, latency: float):
        """添加网络连接"""
        self.connections.append((node1_id, node2_id, latency))
    
    def generate_task(self, task_type: TaskType = None) -> SimulationTask:
        """
        生成随机仿真任务
        
        根据任务类型设置不同的参数:
        - 热仿真: 中等数据量, 中等计算需求
        - 结构仿真: 大数据量, 高计算需求
        - 耦合仿真: 最大数据量和计算需求
        - 实时监控: 小数据量, 低计算需求
        - 数据预处理: 小数据量, 中等计算需求
        """
        task_id = f"task_{len(self.all_tasks):04d}"
        
        if task_type is None:
            task_type = random.choice(list(TaskType))
        
        # 根据任务类型设置参数
        type_params = {
            TaskType.THERMAL_SIMULATION: (50, 500, 100, 1000, 500),
            TaskType.STRUCTURAL_SIMULATION: (100, 1000, 500, 5000, 1000),
            TaskType.COUPLED_SIMULATION: (200, 2000, 1000, 10000, 2000),
            TaskType.REAL_TIME_MONITOR: (10, 50, 10, 100, 50),
            TaskType.DATA_PREPROCESS: (20, 100, 50, 500, 100)
        }
        
        data_min, data_max, compute_min, compute_max, deadline = type_params[task_type]
        
        task = SimulationTask(
            task_id=task_id,
            task_type=task_type,
            data_size=random.uniform(data_min, data_max),
            compute_demand=random.uniform(compute_min, compute_max),
            deadline=deadline,
            priority=random.randint(1, 10),
            arrival_time=self.current_time
        )
        
        return task
    
    def offload_decision(self, task: SimulationTask) -> Tuple[str, float]:
        """
        任务卸载决策算法
        
        策略:
        1. 计算在边缘节点和云端执行的估计延迟
        2. 考虑网络延迟和计算延迟
        3. 选择满足截止时间且延迟最小的方案
        
        决策逻辑:
        - 优先评估所有边缘节点
        - 然后评估云端节点
        - 优先选择满足截止时间的边缘节点(数据本地化处理)
        - 如果没有满足截止时间的选项,选择延迟最小的
        
        Returns:
            (目标节点ID, 估计延迟)
        """
        options = []
        
        # 评估边缘节点
        for node in self.edge_nodes.values():
            if node.can_accept(task):
                latency = node.estimate_completion_time(task)
                options.append((node.node_id, latency, 'edge'))
        
        # 评估云端节点
        if self.cloud_node:
            # 云端计算时间(假设云端算力更强)
            cloud_compute_time = task.compute_demand / (self.cloud_node.cpu_cores * 
                                                        self.cloud_node.cpu_frequency) * 1000
            # 上传延迟
            upload_latency = task.data_size * 8 / self.cloud_node.bandwidth_mbps * 1000
            # 总延迟(考虑往返)
            total_latency = self.cloud_node.latency_ms + upload_latency * 2 + cloud_compute_time
            options.append((self.cloud_node.node_id, total_latency, 'cloud'))
        
        if not options:
            return None, float('inf')
        
        # 选择满足截止时间的最佳选项
        valid_options = [(nid, lat, loc) for nid, lat, loc in options if lat <= task.deadline]
        
        if valid_options:
            # 优先选择边缘节点(数据本地化处理)
            edge_options = [(nid, lat, loc) for nid, lat, loc in valid_options if loc == 'edge']
            if edge_options:
                return min(edge_options, key=lambda x: x[1])[:2]
            return min(valid_options, key=lambda x: x[1])[:2]
        else:
            # 如果没有满足截止时间的,选择延迟最小的
            return min(options, key=lambda x: x[1])[:2]
    
    def schedule_tasks(self):
        """
        调度待处理任务
        
        调度流程:
        1. 遍历等待队列中的任务
        2. 对每个任务调用卸载决策算法
        3. 将任务分配到选定的节点
        4. 从等待队列中移除已调度的任务
        """
        scheduled = []
        
        for task in self.pending_tasks[:]:
            target_id, estimated_latency = self.offload_decision(task)
            
            if target_id:
                if target_id in self.edge_nodes:
                    self.edge_nodes[target_id].assign_task(task, self.current_time)
                elif self.cloud_node and target_id == self.cloud_node.node_id:
                    self.cloud_node.assign_task(task, self.current_time)
                
                self.pending_tasks.remove(task)
                scheduled.append((task, target_id, estimated_latency))
        
        return scheduled
    
    def step(self, time_step: float = 10.0):
        """
        执行一个时间步
        
        执行流程:
        1. 更新时间
        2. 处理所有节点的活跃任务
        3. 调度新任务
        4. 收集统计信息
        """
        self.current_time += time_step
        
        # 处理所有节点的任务
        completed = []
        for node in list(self.edge_nodes.values()) + [self.cloud_node]:
            if node:
                completed.extend(node.process_tasks(self.current_time, time_step))
        
        # 调度新任务
        scheduled = self.schedule_tasks()
        
        # 收集统计
        stats = self.collect_statistics()
        self.stats_history.append((self.current_time, stats))
        
        return completed, scheduled
    
    def collect_statistics(self) -> Dict:
        """
        收集平台统计信息
        
        统计指标:
        - 任务数量: 总数、已完成、执行中、等待中
        - 性能指标: 平均延迟、截止时间满足率
        - 资源指标: 边缘利用率、总功耗
        """
        total_tasks = len(self.all_tasks)
        completed_tasks = sum(len(n.completed_tasks) for n in self.edge_nodes.values())
        if self.cloud_node:
            completed_tasks += len(self.cloud_node.completed_tasks)
        
        active_tasks = sum(len(n.active_tasks) for n in self.edge_nodes.values())
        if self.cloud_node:
            active_tasks += len(self.cloud_node.active_tasks)
        
        pending_tasks = len(self.pending_tasks)
        
        # 计算平均延迟和 deadline 满足率
        all_completed = []
        for node in list(self.edge_nodes.values()) + [self.cloud_node]:
            if node:
                all_completed.extend(node.completed_tasks)
        
        avg_latency = np.mean([t.get_latency() for t in all_completed]) if all_completed else 0
        deadline_meet_rate = (sum(1 for t in all_completed if t.is_meet_deadline()) / 
                             len(all_completed) * 100) if all_completed else 0
        
        # 计算总能耗
        total_power = sum(n.get_power_consumption() for n in self.edge_nodes.values())
        if self.cloud_node:
            total_power += self.cloud_node.get_power_consumption()
        
        return {
            'total_tasks': total_tasks,
            'completed': completed_tasks,
            'active': active_tasks,
            'pending': pending_tasks,
            'avg_latency': avg_latency,
            'deadline_meet_rate': deadline_meet_rate,
            'total_power': total_power,
            'edge_utilization': self._get_edge_utilization()
        }
    
    def _get_edge_utilization(self) -> float:
        """获取边缘节点平均利用率"""
        if not self.edge_nodes:
            return 0.0
        
        utilizations = []
        for node in self.edge_nodes.values():
            total_compute = node.cpu_cores * node.cpu_frequency
            used_compute = sum(t.compute_demand * 0.01 for t in node.active_tasks)
            utilizations.append(min(1.0, used_compute / total_compute))
        
        return np.mean(utilizations) * 100


def create_sample_platform() -> EdgeComputingPlatform:
    """
    创建示例边缘计算平台
    
    架构设计:
    - 5个边缘节点: 分布在不同位置,具有不同的计算能力
    - 1个云端节点: 强大的计算能力,但延迟较高
    - 1个网关节点: 连接设备和边缘网络
    - 节点间通过不同延迟的连接互联
    """
    platform = EdgeComputingPlatform()
    
    # 添加边缘节点(模拟工厂车间、基站等)
    edge_configs = [
        ("edge_01", (2, 8), NodeType.EDGE, 8, 2.5, 16, 100, 5),
        ("edge_02", (8, 8), NodeType.EDGE, 8, 2.5, 16, 100, 5),
        ("edge_03", (2, 2), NodeType.EDGE, 4, 2.0, 8, 50, 10),
        ("edge_04", (8, 2), NodeType.EDGE, 4, 2.0, 8, 50, 10),
        ("edge_05", (5, 5), NodeType.FOG, 16, 3.0, 32, 200, 3),
    ]
    
    for node_id, pos, ntype, cores, freq, mem, bw, lat in edge_configs:
        node = EdgeNode(
            node_id=node_id,
            node_type=ntype,
            position=pos,
            cpu_cores=cores,
            cpu_frequency=freq,
            memory_gb=mem,
            bandwidth_mbps=bw,
            latency_ms=lat
        )
        platform.add_edge_node(node)
    
    # 设置云端节点
    cloud_node = EdgeNode(
        node_id="cloud_center",
        node_type=NodeType.CLOUD,
        position=(15, 5),
        cpu_cores=64,
        cpu_frequency=3.5,
        memory_gb=256,
        bandwidth_mbps=1000,
        latency_ms=50
    )
    platform.set_cloud_node(cloud_node)
    
    # 添加网关
    gateway = EdgeNode(
        node_id="gateway_01",
        node_type=NodeType.GATEWAY,
        position=(0, 5),
        cpu_cores=2,
        cpu_frequency=1.5,
        memory_gb=4,
        bandwidth_mbps=500,
        latency_ms=2
    )
    platform.add_gateway(gateway)
    
    # 添加连接
    connections = [
        ("gateway_01", "edge_01", 2),
        ("gateway_01", "edge_03", 3),
        ("edge_01", "edge_02", 2),
        ("edge_01", "edge_05", 1),
        ("edge_02", "edge_04", 2),
        ("edge_02", "edge_05", 1),
        ("edge_03", "edge_04", 2),
        ("edge_04", "edge_05", 1),
        ("edge_05", "cloud_center", 20),
    ]
    
    for n1, n2, lat in connections:
        platform.add_connection(n1, n2, lat)
    
    return platform


def visualize_network_topology(platform: EdgeComputingPlatform, 
                               save_path: str = None):
    """可视化网络拓扑"""
    fig, ax = plt.subplots(figsize=(14, 10))
    
    # 绘制连接
    for n1_id, n2_id, latency in platform.connections:
        n1 = platform.edge_nodes.get(n1_id) or platform.cloud_node
        n2 = platform.edge_nodes.get(n2_id) or platform.cloud_node
        
        if n1 and n2:
            x1, y1 = n1.position
            x2, y2 = n2.position
            
            # 根据延迟设置线宽
            linewidth = max(1, 5 - latency / 5)
            alpha = max(0.3, 1 - latency / 30)
            
            ax.plot([x1, x2], [y1, y2], 'gray', 
                   linewidth=linewidth, alpha=alpha, zorder=1)
            
            # 标注延迟
            mid_x, mid_y = (x1 + x2) / 2, (y1 + y2) / 2
            ax.annotate(f'{latency}ms', (mid_x, mid_y), 
                       fontsize=8, alpha=0.7, ha='center')
    
    # 绘制节点
    node_colors = {
        NodeType.EDGE: '#3498db',
        NodeType.FOG: '#9b59b6',
        NodeType.CLOUD: '#e74c3c',
        NodeType.GATEWAY: '#f39c12'
    }
    
    node_sizes = {
        NodeType.EDGE: 800,
        NodeType.FOG: 1200,
        NodeType.CLOUD: 2000,
        NodeType.GATEWAY: 600
    }
    
    # 绘制边缘节点
    for node in platform.edge_nodes.values():
        x, y = node.position
        color = node_colors[node.node_type]
        size = node_sizes[node.node_type]
        
        circle = Circle((x, y), 0.4, color=color, alpha=0.8, zorder=2)
        ax.add_patch(circle)
        
        # 节点标签
        ax.text(x, y, node.node_id.split('_')[1], 
               ha='center', va='center', fontsize=10, 
               fontweight='bold', color='white', zorder=3)
        
        # 节点信息
        info_text = f'{node.cpu_cores}C/{node.memory_gb}G'
        ax.text(x, y - 0.7, info_text, 
               ha='center', va='top', fontsize=8, alpha=0.8)
    
    # 绘制云端节点
    if platform.cloud_node:
        x, y = platform.cloud_node.position
        cloud_circle = Circle((x, y), 0.6, color=node_colors[NodeType.CLOUD], 
                             alpha=0.8, zorder=2)
        ax.add_patch(cloud_circle)
        ax.text(x, y, 'CLOUD', ha='center', va='center', 
               fontsize=10, fontweight='bold', color='white', zorder=3)
        ax.text(x, y - 0.9, '64C/256G', ha='center', va='top', fontsize=8)
    
    # 绘制网关
    for gateway in platform.gateway_nodes:
        x, y = gateway.position
        gw_circle = Circle((x, y), 0.3, color=node_colors[NodeType.GATEWAY], 
                          alpha=0.8, zorder=2)
        ax.add_patch(gw_circle)
        ax.text(x, y, 'GW', ha='center', va='center', 
               fontsize=8, fontweight='bold', color='white', zorder=3)
    
    # 图例
    legend_elements = [
        plt.Line2D([0], [0], marker='o', color='w', markerfacecolor='#3498db', 
                  markersize=12, label='边缘节点 (Edge)'),
        plt.Line2D([0], [0], marker='o', color='w', markerfacecolor='#9b59b6', 
                  markersize=12, label='雾节点 (Fog)'),
        plt.Line2D([0], [0], marker='o', color='w', markerfacecolor='#e74c3c', 
                  markersize=15, label='云端 (Cloud)'),
        plt.Line2D([0], [0], marker='o', color='w', markerfacecolor='#f39c12', 
                  markersize=10, label='网关 (Gateway)')
    ]
    ax.legend(handles=legend_elements, loc='upper right', fontsize=10)
    
    ax.set_xlim(-2, 18)
    ax.set_ylim(-1, 11)
    ax.set_aspect('equal')
    ax.set_xlabel('X 位置 (km)', fontsize=12)
    ax.set_ylabel('Y 位置 (km)', fontsize=12)
    ax.set_title('边缘计算网络拓扑', fontsize=16, fontweight='bold')
    ax.grid(True, alpha=0.3)
    
    plt.tight_layout()
    
    if save_path:
        plt.savefig(save_path, dpi=150, bbox_inches='tight')
        print(f"拓扑图已保存: {save_path}")
    
    plt.close()


def simulate_and_visualize():
    """运行仿真并生成可视化"""
    print("\n" + "="*60)
    print("边缘计算仿真平台演示")
    print("="*60)
    
    # 创建平台
    platform = create_sample_platform()
    
    # 可视化网络拓扑
    visualize_network_topology(platform, 
                               save_path='边缘计算网络拓扑.png')
    
    # 生成初始任务
    print("\n生成仿真任务...")
    for _ in range(20):
        task = platform.generate_task()
        platform.pending_tasks.append(task)
        platform.all_tasks.append(task)
    
    print(f"初始任务数: {len(platform.pending_tasks)}")
    
    # 运行仿真
    print("\n开始仿真...")
    frames = []
    
    for step in range(50):
        # 随机生成新任务
        if random.random() < 0.3:
            task = platform.generate_task()
            platform.pending_tasks.append(task)
            platform.all_tasks.append(task)
        
        # 执行时间步
        completed, scheduled = platform.step(time_step=10.0)
        
        # 每5步记录一帧
        if step % 5 == 0:
            fig = visualize_platform_state(platform, step)
            
            # 保存为图片
            buf = io.BytesIO()
            fig.savefig(buf, format='png', dpi=100, bbox_inches='tight')
            buf.seek(0)
            frames.append(Image.open(buf))
            plt.close(fig)
        
        if step % 10 == 0:
            stats = platform.stats_history[-1][1] if platform.stats_history else {}
            print(f"步骤 {step:3d}: 完成={stats.get('completed', 0)}, "
                  f"活跃={stats.get('active', 0)}, 等待={stats.get('pending', 0)}, "
                  f"延迟={stats.get('avg_latency', 0):.1f}ms")
    
    # 保存动画
    if frames:
        frames[0].save(
            '边缘计算仿真动态.gif',
            save_all=True,
            append_images=frames[1:],
            duration=500,
            loop=0
        )
        print("\n动画已保存: 边缘计算仿真动态.gif")
    
    # 最终统计
    print("\n" + "="*60)
    print("仿真统计")
    print("="*60)
    final_stats = platform.stats_history[-1][1] if platform.stats_history else {}
    print(f"总任务数: {final_stats.get('total_tasks', 0)}")
    print(f"完成任务: {final_stats.get('completed', 0)}")
    print(f"平均延迟: {final_stats.get('avg_latency', 0):.2f} ms")
    print(f"截止时间满足率: {final_stats.get('deadline_meet_rate', 0):.1f}%")
    print(f"边缘节点利用率: {final_stats.get('edge_utilization', 0):.1f}%")
    print(f"总功耗: {final_stats.get('total_power', 0):.1f} W")
    
    # 绘制统计图表
    plot_simulation_statistics(platform)
    
    return platform


def visualize_platform_state(platform: EdgeComputingPlatform, step: int):
    """
    可视化平台状态
    
    展示四个维度的信息:
    1. 网络拓扑与负载分布
    2. 任务状态分布
    3. 边缘节点利用率
    4. 任务类型分布
    """
    fig, axes = plt.subplots(2, 2, figsize=(16, 12))
    
    # 1. 网络拓扑与任务分布
    ax1 = axes[0, 0]
    
    # 绘制连接
    for n1_id, n2_id, latency in platform.connections:
        n1 = platform.edge_nodes.get(n1_id) or platform.cloud_node
        n2 = platform.edge_nodes.get(n2_id) or platform.cloud_node
        
        if n1 and n2:
            x1, y1 = n1.position
            x2, y2 = n2.position
            ax1.plot([x1, x2], [y1, y2], 'gray', alpha=0.3, zorder=1)
    
    # 绘制节点(大小表示负载)
    for node in platform.edge_nodes.values():
        x, y = node.position
        load = len(node.active_tasks) / node.cpu_cores
        size = 300 + load * 700
        color = plt.cm.RdYlGn(1 - load)
        
        ax1.scatter(x, y, s=size, c=[color], alpha=0.8, zorder=2, edgecolors='black')
        ax1.text(x, y, f'{len(node.active_tasks)}', ha='center', va='center', 
                fontsize=10, fontweight='bold')
    
    if platform.cloud_node:
        x, y = platform.cloud_node.position
        ax1.scatter(x, y, s=800, c='#e74c3c', alpha=0.8, zorder=2, marker='s')
        ax1.text(x, y, 'C', ha='center', va='center', fontsize=12, 
                fontweight='bold', color='white')
    
    ax1.set_xlim(-2, 18)
    ax1.set_ylim(-1, 11)
    ax1.set_aspect('equal')
    ax1.set_title(f'网络拓扑与负载分布 (步骤 {step})', fontsize=12, fontweight='bold')
    ax1.grid(True, alpha=0.3)
    
    # 2. 任务状态分布
    ax2 = axes[0, 1]
    
    task_status = ['等待中', '执行中', '已完成']
    pending = len(platform.pending_tasks)
    active = sum(len(n.active_tasks) for n in platform.edge_nodes.values())
    if platform.cloud_node:
        active += len(platform.cloud_node.active_tasks)
    completed = sum(len(n.completed_tasks) for n in platform.edge_nodes.values())
    if platform.cloud_node:
        completed += len(platform.cloud_node.completed_tasks)
    
    values = [pending, active, completed]
    colors = ['#f39c12', '#3498db', '#2ecc71']
    
    bars = ax2.bar(task_status, values, color=colors, alpha=0.8, edgecolor='black')
    ax2.set_ylabel('任务数量', fontsize=11)
    ax2.set_title('任务状态分布', fontsize=12, fontweight='bold')
    
    for bar, val in zip(bars, values):
        ax2.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 0.5, 
                str(val), ha='center', va='bottom', fontsize=11, fontweight='bold')
    
    # 3. 节点利用率
    ax3 = axes[1, 0]
    
    node_ids = []
    utilizations = []
    
    for node_id, node in platform.edge_nodes.items():
        node_ids.append(node_id.split('_')[1])
        total_compute = node.cpu_cores * node.cpu_frequency
        used_compute = sum(t.compute_demand * 0.01 for t in node.active_tasks)
        util = min(100, used_compute / total_compute * 100)
        utilizations.append(util)
    
    colors = plt.cm.RdYlGn_r(np.array(utilizations) / 100)
    bars = ax3.barh(node_ids, utilizations, color=colors, alpha=0.8, edgecolor='black')
    ax3.set_xlabel('利用率 (%)', fontsize=11)
    ax3.set_title('边缘节点利用率', fontsize=12, fontweight='bold')
    ax3.set_xlim(0, 100)
    
    for bar, val in zip(bars, utilizations):
        ax3.text(val + 2, bar.get_y() + bar.get_height()/2, 
                f'{val:.1f}%', va='center', fontsize=10)
    
    # 4. 任务类型分布
    ax4 = axes[1, 1]
    
    task_types = {}
    for task in platform.all_tasks:
        ttype = task.task_type.value
        task_types[ttype] = task_types.get(ttype, 0) + 1
    
    if task_types:
        labels = list(task_types.keys())
        sizes = list(task_types.values())
        colors_pie = plt.cm.Set3(np.linspace(0, 1, len(labels)))
        
        wedges, texts, autotexts = ax4.pie(sizes, labels=labels, autopct='%1.1f%%',
                                           colors=colors_pie, startangle=90)
        ax4.set_title('任务类型分布', fontsize=12, fontweight='bold')
    
    plt.tight_layout()
    return fig

代码深度解析

8.1 核心类设计

8.1.1 SimulationTask 类

SimulationTask 类代表一个仿真任务,包含任务的静态属性(如数据量、计算需求)和动态状态(如开始时间、完成时间)。

关键方法解析:

def get_latency(self) -> float:
    """获取任务延迟"""
    if self.completion_time is None:
        return float('inf')
    return self.completion_time - self.arrival_time

这个方法计算任务从到达至完成的总延迟。如果任务尚未完成,返回无穷大。

def is_meet_deadline(self) -> bool:
    """检查是否满足截止时间"""
    return self.get_latency() <= self.deadline

这个方法检查任务是否在截止时间前完成,是评估系统性能的重要指标。

8.1.2 EdgeNode 类

EdgeNode 类代表边缘计算节点,管理节点的资源和任务。

关键方法解析:

def estimate_completion_time(self, task: SimulationTask) -> float:
    """估计任务完成时间"""
    if not self.can_accept(task):
        return float('inf')
    
    # 计算时间 = 计算需求 / 可用计算能力
    compute_time = task.compute_demand / self.get_available_compute() * 1000
    
    # 传输时间 = 数据量 / 带宽
    transmission_time = task.data_size * 8 / self.bandwidth_mbps * 1000
    
    return self.latency_ms + transmission_time + compute_time

这个方法实现了任务完成时间的估计模型,包含三个组成部分:

  1. 基础延迟:网络传输的基础延迟
  2. 传输时间:数据传输所需时间
  3. 计算时间:任务执行所需时间
8.1.3 EdgeComputingPlatform 类

EdgeComputingPlatform 类是系统的核心,负责整体调度和管理。

关键方法解析:

def offload_decision(self, task: SimulationTask) -> Tuple[str, float]:
    """任务卸载决策算法"""
    options = []
    
    # 评估边缘节点
    for node in self.edge_nodes.values():
        if node.can_accept(task):
            latency = node.estimate_completion_time(task)
            options.append((node.node_id, latency, 'edge'))
    
    # 评估云端节点
    if self.cloud_node:
        cloud_compute_time = task.compute_demand / (self.cloud_node.cpu_cores * 
                                                    self.cloud_node.cpu_frequency) * 1000
        upload_latency = task.data_size * 8 / self.cloud_node.bandwidth_mbps * 1000
        total_latency = self.cloud_node.latency_ms + upload_latency * 2 + cloud_compute_time
        options.append((self.cloud_node.node_id, total_latency, 'cloud'))
    
    # 选择满足截止时间的最佳选项
    valid_options = [(nid, lat, loc) for nid, lat, loc in options if lat <= task.deadline]
    
    if valid_options:
        # 优先选择边缘节点
        edge_options = [(nid, lat, loc) for nid, lat, loc in valid_options if loc == 'edge']
        if edge_options:
            return min(edge_options, key=lambda x: x[1])[:2]
        return min(valid_options, key=lambda x: x[1])[:2]
    else:
        # 选择延迟最小的
        return min(options, key=lambda x: x[1])[:2]

这是核心的卸载决策算法,实现了以下策略:

  1. 全面评估:计算任务在所有边缘节点和云端的执行延迟
  2. 截止时间优先:优先选择满足截止时间的方案
  3. 边缘优先:在满足截止时间的方案中,优先选择边缘节点(数据本地化处理)
  4. 降级策略:如果没有满足截止时间的方案,选择延迟最小的

8.2 可视化实现

代码使用 Matplotlib 实现了丰富的可视化功能:

8.2.1 网络拓扑可视化
def visualize_network_topology(platform, save_path=None):
    fig, ax = plt.subplots(figsize=(14, 10))
    
    # 绘制连接
    for n1_id, n2_id, latency in platform.connections:
        # 根据延迟设置线宽和透明度
        linewidth = max(1, 5 - latency / 5)
        alpha = max(0.3, 1 - latency / 30)
        ax.plot([x1, x2], [y1, y2], 'gray', linewidth=linewidth, alpha=alpha)
    
    # 绘制节点
    for node in platform.edge_nodes.values():
        circle = Circle((x, y), 0.4, color=color, alpha=0.8)
        ax.add_patch(circle)

可视化特点:

  • 延迟感知:连接线的宽度和透明度根据延迟动态调整
  • 节点区分:不同类型的节点使用不同颜色
  • 信息丰富:节点上标注资源配置信息
8.2.2 动态状态可视化
def visualize_platform_state(platform, step):
    fig, axes = plt.subplots(2, 2, figsize=(16, 12))
    
    # 四个子图:网络拓扑、任务状态、节点利用率、任务类型
    # ...

动态可视化展示了系统的实时状态,帮助理解边缘计算平台的运行机制。


运行结果分析

9.1 边缘计算网络拓扑

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

拓扑特点:

  • 5个边缘节点分布在不同位置,模拟工厂车间或基站
  • 1个雾节点(edge_05)作为中间层,连接边缘和云端
  • 1个云端节点提供强大的计算能力
  • 1个网关节点作为入口

延迟设计:

  • 边缘节点间延迟:1-3ms
  • 边缘到雾节点:1-3ms
  • 雾节点到云端:20ms

9.2 仿真动态过程

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

动画展示了50个时间步的系统演化:

  • 网络拓扑与负载:节点大小和颜色表示负载情况
  • 任务状态:等待中、执行中、已完成的任务数量
  • 节点利用率:各边缘节点的资源利用率
  • 任务类型:不同类型任务的分布

9.3 仿真统计

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

关键指标趋势:

  1. 任务数量:已完成任务持续增长,活跃任务趋于稳定
  2. 平均延迟:初期波动后趋于稳定
  3. 截止时间满足率:反映系统满足实时性要求的能力
  4. 功耗与利用率:资源使用效率的度量

9.4 边缘-云协同策略对比

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

四种策略对比结果:

策略 平均延迟 满足率 完成任务 功耗
纯边缘计算 374.38ms 37.5% 16 121.2W
纯云计算 333.33ms 33.3% 15 92.5W
智能卸载 365.56ms 63.0% 27 86.9W
协同计算 423.53ms 41.2% 17 119.4W

分析:

  • 智能卸载策略表现最佳,截止时间满足率最高(63%)
  • 智能卸载能够动态选择最优执行位置,平衡延迟和资源利用
  • 纯边缘和纯云策略各有局限,协同策略需要更精细的调度

9.5 5G实时仿真应用

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

四种应用场景:

场景 截止时间 实际延迟 满足率
自动驾驶 10ms 5.00ms 100%
AR/VR仿真 20ms - 0%
工业控制 5ms 15.75ms 25%
远程手术 1ms - 0%

分析:

  • 5G的超低延迟(1ms)使得自动驾驶等应用能够满足实时性要求
  • 远程手术等极端延迟要求的场景仍然面临挑战
  • 需要结合边缘计算和5G网络切片技术

进阶挑战

10.1 编程练习

练习1:改进卸载决策算法

当前的卸载决策仅考虑延迟,尝试增加能耗因素:

def offload_decision_with_energy(self, task):
    """
    考虑能耗的卸载决策
    
    目标:最小化 延迟 + α * 能耗
    """
    alpha = 0.1  # 能耗权重系数
    
    best_option = None
    best_score = float('inf')
    
    for node in self.edge_nodes.values():
        if node.can_accept(task):
            latency = node.estimate_completion_time(task)
            energy = node.get_power_consumption() * latency / 1000
            score = latency + alpha * energy
            
            if score < best_score:
                best_score = score
                best_option = node.node_id
    
    return best_option

练习2:实现负载均衡调度

实现一个考虑节点负载的调度策略:

def schedule_with_load_balance(self):
    """
    负载均衡调度
    
    策略:将任务分配到负载最轻的节点
    """
    for task in self.pending_tasks[:]:
        # 计算各节点的负载
        node_loads = {}
        for node_id, node in self.edge_nodes.items():
            if node.can_accept(task):
                load = len(node.active_tasks) / node.cpu_cores
                node_loads[node_id] = load
        
        if node_loads:
            # 选择负载最小的节点
            best_node = min(node_loads, key=node_loads.get)
            self.edge_nodes[best_node].assign_task(task, self.current_time)
            self.pending_tasks.remove(task)

练习3:实现任务优先级队列

使用优先级队列替代普通列表:

import heapq

class PriorityTaskQueue:
    def __init__(self):
        self.queue = []
        self.counter = 0
    
    def push(self, task):
        # 优先级高的先执行,相同优先级按到达时间
        heapq.heappush(self.queue, (-task.priority, task.arrival_time, self.counter, task))
        self.counter += 1
    
    def pop(self):
        if self.queue:
            return heapq.heappop(self.queue)[-1]
        return None

10.2 思考题

  1. 延迟与能耗的权衡:在实际系统中,如何平衡延迟和能耗的优化目标?

  2. 动态网络环境:当网络延迟和带宽动态变化时,卸载决策如何自适应调整?

  3. 多任务协同:如果多个任务之间存在依赖关系,如何设计调度策略?

  4. 边缘节点故障:当某个边缘节点故障时,系统如何保证服务连续性?

  5. 5G与边缘计算融合:5G网络切片如何与边缘计算协同优化?


总结与习题

11.1 知识点总结

本主题涵盖了边缘计算与仿真的核心内容:

理论基础:

  • 边缘计算的定义、特点和发展背景
  • 边缘计算与云计算的关系和协同
  • 边缘计算的关键技术(虚拟化、任务卸载、边缘智能)

架构设计:

  • 三层架构模型(云端、雾层、边缘层)
  • 边缘节点类型(边缘服务器、微边缘、智能网关)
  • 网络拓扑设计(星型、网状、层次)

算法实现:

  • 任务卸载决策算法
  • 资源调度算法(FCFS、SJF、优先级、负载均衡)
  • 延迟和能耗模型

应用实践:

  • 5G与边缘计算的融合
  • 实时仿真应用场景
  • 边缘-云协同计算模式

11.2 课后习题

习题1:概念理解

  1. 解释边缘计算与传统云计算的主要区别。
  2. 什么是任务卸载?卸载决策需要考虑哪些因素?
  3. 描述边缘-云协同计算的三种模式。

习题2:算法设计

  1. 设计一个考虑任务截止时间的调度算法。
  2. 如何实现边缘节点间的负载均衡?
  3. 设计一个基于机器学习的卸载决策模型。

习题3:应用分析

  1. 分析5G技术如何赋能实时仿真应用。
  2. 针对智能制造场景,设计边缘计算解决方案。
  3. 讨论边缘计算在数字孪生中的应用。

习题4:编程实践

  1. 扩展代码,实现任务取消功能。
  2. 添加网络故障模拟,测试系统容错能力。
  3. 实现一个简单的REST API,支持远程任务提交。

参考资料

12.1 学术论文

  1. Shi, W., Cao, J., Zhang, Q., Li, Y., & Xu, L. (2016). Edge computing: Vision and challenges. IEEE Internet of Things Journal, 3(5), 637-646.

  2. Mao, Y., You, C., Zhang, J., Huang, K., & Letaief, K. B. (2017). A survey on mobile edge computing: The communication perspective. IEEE Communications Surveys & Tutorials, 19(4), 2322-2358.

  3. Mach, P., & Becvar, Z. (2017). Mobile edge computing: A survey on architecture and computation offloading. IEEE Communications Surveys & Tutorials, 19(3), 1628-1656.

12.2 技术文档

  1. ETSI GS MEC 003: Mobile Edge Computing (MEC); Framework and Reference Architecture
  2. 3GPP TS 23.501: System Architecture for the 5G System
  3. OpenFog Reference Architecture for Fog Computing

12.3 开源项目

  1. KubeEdge: Kubernetes Native Edge Computing Framework
  2. EdgeX Foundry: Open Source IoT Edge Platform
  3. Baetyl: Extend cloud computing, data and service seamlessly to edge devices

12.4 推荐书籍

  1. 《边缘计算:原理、架构与实践》- 施巍松等
  2. 《5G移动通信系统设计与标准详解》- 刘光毅等
  3. 《云计算与分布式系统:从并行处理到物联网》- Kai Hwang等

下一主题预告

主题067:量子计算与仿真

在下一主题中,我们将探索量子计算在工程仿真中的应用:

  • 量子计算基础原理
  • 量子算法在仿真中的优势
  • 量子-经典混合计算架构
  • 量子仿真软件与工具

敬请期待!


本教程由仿真教学团队精心编写,如有疑问或建议,欢迎交流讨论。

更多推荐