我正在阅读《英特尔® 64 和 IA-32 架构软件开发人员手册:系统编程指南》以了解有关操作系统如何工作的更多信息,但有一些事情我无法弄清楚。
因此,我了解到操作系统内核代码映射到所有进程的虚拟地址空间,并以系统调用或中断/异常的特权运行,内核可以通过 IPI 进行通信,进程的线程作为 x86 架构中的任务运行,线程切换需要更改任务寄存器以指向下一个任务状态段等。我也知道分页、保护和所有这些是如何工作的。
然而,当存在多核时,我开始对执行某些“全局”内核操作(例如线程切换)的核心感到困惑。我在大文档中找不到它。我主要关心的是线程切换。当线程量被消耗时,哪个CORE执行线程调度,是BSP处理器在执行还是这是由BSP和所有AP执行的分布式任务?
当收到切换线程所需的时间中断时,是否所有核心都收到?在这种情况下他们如何管理共享资源?(因此,如果其中一个核心调度了一个线程,其他核心也不会调度它)
提前致谢!!
不同的操作系统是不同的。然而:
用于短期决策;在 2 个或更多 CPU 之间同步事物会耗费时间、导致缓存效率低下并降低性能;因此,希望每个 CPU 能够独立运行,CPU 之间不共享数据(例如,每个 CPU 都有等待线程的队列,并且每个 CPU 都有一个独立的调度程序)。
长期而言;你必须关心CPU负载平衡(例如,你不希望一个CPU超载,而其他CPU则空闲/浪费);电源管理决策(例如,如果 CPU 过热并且必须进行节流)和其他可能的功能(例如“热插拔 CPU”支持)可能会加剧 CPU 负载不平衡。
典型的现代调度程序是这些目标之间的折衷方案。例如,每个 CPU 的“大部分独立”调度程序(但允许一个 CPU 以某种方式将线程放在不同 CPU 调度程序的数据结构上,以移动/迁移线程以实现负载平衡)。
几乎所有线程切换都是由线程阻塞(必须等待获取互斥锁、等待磁盘 IO、等待时间过去、等待用户输入……)或较高优先级线程解除阻塞并立即抢占某个线程引起的。当前正在运行较低优先级线程(因为无论较高优先级线程正在等待什么发生)。由线程消耗其量而引起的任务切换只是一种几乎不需要的最坏情况的保护措施;并且不同 CPU 上的线程实际上不可能同时结束其时间片。典型/现代的方法是,当切换到线程时,CPU 的调度程序确定该线程应该被允许拥有的最大时间,然后要求计时器在确定的时间已过时通知它。大多数硬件为每个CPU都有一个定时器;所以“时间量子”的东西最终都是“每个CPU,CPU之间没有共享”。更大的问题是,通常相同的“每个 CPU”计时器也用于其他所有事情(例如 TCP/IP 超时、“
sleep()
“,跟踪事物闲置了多长时间,...)因此您最终会得到一个具有更多开销的通用系统,其中调度程序创建“计时器事件”然后稍后取消它的成本,因为不需要它仍然变成一堆明显愚蠢的膨胀。