【问题标题】:RTOS: Context Switching - Calculate TCB Lookup vs. Memory AccessRTOS:上下文切换 - 计算 TCB 查找与内存访问
【发布时间】:2022-01-05 20:08:09
【问题描述】:

目前我正在为带有 Cortex-M4 处理器的 STM32F4VE 编写一个轻量级的 RTOS。多个进程之间以循环方式进行上下文切换工作正常,但尽可能优化内核机制是我的爱好。 TCB 堆叠在 SRAM 底部的保留区域中。

在每次上下文切换时,我都会像这样搜索下一个 TCB: ((pid + 1) * TCB_Size) + TCB_BASE_ADRESS.

如果 pid 等于任务数量,我将其重置为 0。这是通过 if 三元运算符完成的,而不是昂贵的模运算。

当切换时,例如每 8 毫秒,CPU 必须每次都执行此乘法运算。 我想知道在生成每个任务时预先计算这些 tcb 地址并将它们直接写入内存是否会更有效。

第二种变体将在每次上下文切换时访问内存 2 次 - 获取 tcb 的地址,获取 tcb。否则会有一个“昂贵”的乘法。

哪种变体更有效? 如果没有人有绝对的答案,我将重写概念并做一个简单的基准测试。

谢谢!

【问题讨论】:

    标签: performance memory rtos


    【解决方案1】:

    在每次上下文切换时,我都会像这样搜索下一个 TCB:((pid + 1) * TCB_Size) + TCB_BASE_ADRESS。

    只需使用循环链表即可;喜欢:

        pointer_to_next_task_TCB = pointer_to_this_task_TCB->next;
        switch_to_task(pointer_to_next_task_TCB);
    

    ... 其中pointer_to_this_task_TCB 是全局变量(仅限单 CPU)或 CPU 特定变量;其中switch_to_task(pointer_to_next_task_TCB); 确保pointer_to_this_task_TCB = pointer_to_next_task_TCB; 作为任务切换的一部分(或之后)完成。

    请注意,当任务阻塞时(睡眠、等待磁盘 IO、等待获取互斥锁,...),您需要将它们从链表中删除,以确保调度程序不会为它们分配 CPU 时间,然后执行尽快切换任务(在任务的时间片结束之前不浪费 CPU 时间);当任务解除阻塞时(时间延迟到期,数据从磁盘到达,......)它们需要重新插入到链表中,以便调度程序再次给它们CPU时间,并且它们需要插入到正确的位置(列表的当前末尾)以防止拒绝服务/CPU hogs(例如,任务故意阻塞极短的时间以不断地放回到列表的开头并获得一个全新的时间片,而其他任务则没有CPU 时间)。

    不要忘记,在正常情况下,大多数任务大部分时间都被阻塞(并且它们的 TCB 大部分时间都不在调度程序的链表上);并且列表几乎从不按 PID 顺序排列。

    例如;如果有 100 个任务,其中 96 个任务被阻塞等待,那么调度器的链表可能是“PID 9, PID 74, PID 31, PID 46, then back to PID 9 again”。

    【讨论】:

      猜你喜欢
      • 2020-04-17
      • 1970-01-01
      • 2020-10-23
      • 1970-01-01
      • 2011-03-03
      • 2011-01-27
      • 1970-01-01
      • 2012-09-19
      相关资源
      最近更新 更多