在裸机系统(嵌入式微控制器,无MMU,无分页)上哪些更贵?完整的上下文切换(寄存器保存和恢复)或函数调用(激活记录分配)?
据我所知,这高度依赖于调用约定和硬件功能,但我该如何评估它?
编辑:
为了提供更多上下文,我正在尝试建模两种调度方案。第一个是先发制人的调度程序,在任务之间切换上下文。第二个是函数指针运行队列,其中任务是状态机,分为几个可以进行的函数调用(在IO事件驱动的基础上进行排队)。
在大多数情况下,我可以收集关于我的任务需要多长时间(IO和CPU时间)的良好数据,但我需要一些帮助来计算在模型中添加常量的额外开销成本。
答案 0 :(得分:1)
由于系统调用触发器上下文切换是函数调用,并且可以触发上下文切换的硬件中断类似,(并且需要调用事件/信号量,以及跳转/调用调度程序入口点,为了发出上下文切换信号,我想说除非传递了不合理数量的参数,否则函数调用会更便宜的CPU循环。
这闻起来就像一个XY问题 - 你为什么这么问?上下文切换和函数调用几乎是正交的 - 一个是基于堆栈的机制,另一个是完全选择不同的堆栈。
答案 1 :(得分:0)
您可以通过对比技术及其对整体数据移动的实际影响来评估这一点。
例如,在6502上,中断按下:程序计数器,X,Y,A和状态寄存器。这是6个字节的实际数据,需要7个CPU周期。
当然,6502是比现代设计简单得多的CPU,但它是问题的一个基本例子。
现在,函数调用可以说与Jump子例程一样少,它只是将当前PC推送到堆栈,然后将PC更改为新位置。在6502上,JSR花费了6个周期。
如果您将JSR和BRK(6502上的软件中断)视为基元,则JSR比BRK便宜1个周期。这超出了建立呼叫帧的成本。
大多数上下文切换都是自动完成的(通过计时器或其他)来模拟多处理。但是有些系统使用CPU陷阱原语进行系统调用(如MS-DOS中的INT和旧Mac OS中的TRAP)。因此,软中断仍然需要站立堆栈帧,就像正常的子程序一样。
最后,JSR可能比任何更高级别的交换机制更便宜,仅仅因为它非常轻巧。中断机制通常具有间接机制(这就是为什么它们在系统调用中如此使用),子程序没有。编译器在编译时管理子例程地址。
但这些是考虑原始绩效的考虑因素。