Task08 总结

在datawhale的图神经网络学习中,从2021.06.14到2021.07.10,完成了7个任务,涵盖了PyG库配置、消息传递范式、GCN、GAT、超大图处理、图表征学习和图预测等。通过学习,深化了对GNN原理的理解,掌握了数据预处理和超大规模图的处理技巧。

本次参加datawhale的图神经网络学习,从2021.06.14-2021.07.10,共完成了7个task,以下为task总结:

  • Task 01 简单图论与环境配置与PyG库
    主要学习Pytorch和PyG库的安装以及相关环境配置,因为之前有安装过,所以这个task混过去了。
  • Task 02 消息传递范式
    学习GNN中的消息传递范式,对GNN的原理了解更加清楚,但对MessagePassing基类每个函数的作用还是有点不清楚,以后有机会再弄清楚。
  • Task 03 基于图神经网络的节点表征学习
    学习图神经网络的一般过程,应用了GCN和GAT。
  • Task 04 数据完整存储与内存的数据集类+节点预测与边预测任务实践
    学习利用InMemoryDataset基类处理数据,虽然以前用过,但通过这次学习更加了解了数据预处理的过程。
  • Task 05 超大图上的节点表征学习。
    学习Cluster-GCN算法,用于处理超大图。
  • Task 06 基于图神经网络的图表征学习方法
    学习基于图同构网络(Graph Isomorphism Network, GIN)的图表征网络。
  • Task 07 图预测任务实践
    学习创建超大规模数据集。
在实时操作系统(RTOS)中,**Task Context(任务上下文)** 是指一个任务在运行时所依赖的全部“状态信息”。当 RTOS 进行任务切换(Task Switching)时,必须保存当前任务的上下文,并恢复下一个任务的上下文,以确保每个任务都能从中断处继续执行。 --- ### 一、什么是 Task Context? > ✅ **Task Context = CPU 寄存器状态 + 程序执行位置 + 堆栈数据** 它包括: - CPU 通用寄存器(R0-R12 在 ARM Cortex-M) - 程序计数器(PC) - 链接寄存器(LR,返回地址) - 程序状态寄存器(PSR,如 APSR) - 主堆栈指针(MSP)或进程堆栈指针(PSP) - 浮点寄存器(如果启用 FPU) 这些信息被保存在任务的 **堆栈空间** 中。 --- ### 二、为什么需要保存和恢复任务上下文? RTOS 是抢占式或多任务系统,多个任务“并发”运行。但实际上只有一个 CPU 核心,所以通过时间片轮转或优先级调度实现并发。 ```text +------------------+ +------------------+ | Task A | | Task B | | Running | ---> | Running | | R0=1, R1=5 | | R0=3, R1=8 | | PC=0x08001234 | | PC=0x08005678 | +------------------+ +------------------+ ``` 当从 Task A 切换到 Task B 时: 1. 保存 Task A 的所有寄存器值到它的堆栈(`Save Context`) 2. 恢复 Task B 的寄存器值从它的堆栈(`Restore Context`) 3. 跳转到 Task B 上次停止的位置继续执行 这就是 **上下文切换(Context Switch)**。 --- ### 三、FreeRTOS 中的任务上下文示例(ARM Cortex-M) #### 1. 任务创建时初始化上下文 ```c void vTaskStartScheduler(void) { // 创建任务时,手动构造初始上下文 pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x01000000UL; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxCode; /* PC = 任务函数入口 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) prvTaskExit; /* LR = 退出函数(不应到达) */ for( ;; ) { pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0; /* R12, R3, R2, R1 */ } pxTopOfStack -= 4; *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 = 参数 */ pxTopOfStack -= 8; /* R11 ~ R4 = 初始化为 0 */ memset(pxTopOfStack, 0, 8 * sizeof(StackType_t)); } ``` > ⚙️ 这段代码模拟了任务第一次运行前的“假返回”状态:一旦调度器启动,就会从堆栈中弹出 PC 和寄存器,开始执行任务函数。 --- #### 2. 上下文切换发生时机 - SysTick 中断触发调度 - 当前任务调用 `vTaskDelay()` - 高优先级任务就绪(如信号量释放) - 执行 `taskYIELD()` #### 3. 汇编层上下文切换(Cortex-M PendSV Handler) ```armasm PendSV_Handler: CPSID I ; 关中断(防止嵌套) MRS R0, PSP ; 获取当前任务堆栈指针 ISB LDR R1, =pxCurrentTCB ; 获取当前 TCB 地址 LDR R1, [R1] STR R0, [R1] ; 将 PSP 存入当前 TCB -> pxTopOfStack ; 调用用户函数选择下一个任务 BL vTaskSwitchContext LDR R1, =pxCurrentTCB LDR R1, [R1] LDR R0, [R1] ; 获取新任务的 pxTopOfStack MSR PSP, R0 ; 设置 PSP ISB ORR LR, LR, #0x04 ; 设置 EXC_RETURN 为使用 PSP CPSIE I ; 开中断 BX LR ; 返回线程模式,自动出栈 ``` > 🧠 此汇编代码完成两个核心操作: > - 保存旧任务上下文(通过 PSP 压栈) > - 恢复新任务上下文(通过 PSP 弹栈) --- ### 四、上下文切换过程详解(图文分解) ```text [Before Switch] Task A 运行中: R0=1, R1=2, ..., PC=0x08001000 PSP → [R0][R1][R2]...[PC][xPSR] ← 保存在 Task A 的堆栈 [Tick Interrupt → PendSV] 1. 触发 PendSV 2. CPU 自动压入基本上下文(R0-R3, R12, LR, PC, xPSR) 3. PendSV Handler 手动压入剩余寄存器(R4-R11) [Save Task A Context] PendSV 把 Task A 的完整上下文保存到其堆栈 [Load Task B Context] PendSV 从 Task B 的堆栈恢复所有寄存器(R4-R11, R0-R3, R12, LR, PC, xPSR) 设置 PSP 指向 Task B 堆栈顶部 [Return from PendSV] BX LR 自动触发出栈,CPU 跳转到 Task B 的 PC 继续执行 ``` --- ### 五、如何查看任务上下文?(调试技巧) #### 方法 1:使用调试器查看堆栈内容 在断点暂停后: - 查看 `pxTopOfStack` 字段(在 `TCB_t` 结构体中) - 展开堆栈内存,观察是否包含 PC、LR、R0-R12 等 #### 方法 2:打印任务状态快照 ```c void print_task_context(TaskHandle_t task) { TaskStatus_t status; vTaskGetInfo(task, &status, pdTRUE, eInvalid); printf("Task: %s\n", status.pcTaskName); printf("State: %d\n", status.eCurrentState); printf("Priority: %d\n", status.uxCurrentPriority); printf("Stack High Water Mark: %u\n", status.usStackHighWaterMark); printf("Stack Ptr: 0x%08X\n", (unsigned int)status.pxStackBase); } ``` --- ### 六、常见问题与优化建议 | 问题 | 解决方案 | |------|----------| | 上下文切换太慢 | 减少保存/恢复的寄存器数量(如关闭 FPU) | | 堆栈溢出导致上下文损坏 | 启用 `configCHECK_FOR_STACK_OVERFLOW` | | 中断中频繁触发调度 | 使用 `xHigherPriorityTaskWoken` 延迟调度 | | 多个任务共享同一堆栈 | ❌ 错误!每个任务必须有独立堆栈 | --- ### 七、总结 | 项目 | 内容 | |------|------| | **Task Context 定义** | 任务运行所需的全部 CPU 状态 | | **包含内容** | R0-R12, PC, LR, PSR, PSP, FPU 寄存器等 | | **存储位置** | 每个任务私有的堆栈空间 | | **切换机制** | PendSV + 汇编保存/恢复寄存器 | | **性能影响** | 上下文切换时间 ≈ 几百纳秒 ~ 几微秒(取决于架构) | | **调试工具** | 调试器、SystemView、Tracealyzer | ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值