14

在两个线程之间的上下文切换中究竟保存和恢复了什么

  • 在同一个过程中
  • 两个进程之间
4

4 回答 4

11

这是一个相当复杂的问题,因为答案取决于许多事情:

  1. 有问题的 CPU
    • 即使在同一个系列中,它也可能有很大差异,例如为 SSE/MMX 操作添加的附加寄存器。
  2. 操作系统,因为它控制触发上下文切换的处理程序,并决定是否使用 CPU 的硬件(如果有)来协助上下文切换。
    • 例如,Windows 不使用可以为您执行大部分上下文切换存储的 Intel 硬件,因为它不存储浮点寄存器。
  3. 程序启用的任何优化都知道它自己的要求并能够通知操作系统这一点
    • 也许表明它没有使用 FP 寄存器,所以不要理会它们
    • 在像大多数 RISC 设计这样具有大量寄存器文件的架构中,知道您只需要这些寄存器的较小子集会带来相当大的好处

至少需要保存正在使用的通用寄存器和程序计数器寄存器(假设大多数当前 CISC/RISC 样式通用 CPU 的通用设计)。

请注意,尝试只做与上下文切换相关的最小工作量是一些学术兴趣的话题

Linux 显然在公共领域有更多关于这方面的信息,尽管我的参考资料可能有点过时了。

有一个“task_struct”,其中包含大量与任务状态以及任务所针对的进程相关的字段。

其中之一是“thread_struct”</p>

/* 此任务的 CPU 特定状态 */
- struct thread_struct thread;
保存有关缓存 TLS 描述符、调试寄存器、
故障信息、浮点、虚拟 86 模式或 IO 权限的信息。

每个体系结构都定义了自己的 thread_struct,它标识了保存在交换机上的寄存器和其他值。

由于重命名寄存器的存在允许多个飞行指令(通过超标量或流水线相关的架构设计),这进一步复杂化。上下文切换的恢复阶段可能会依赖于 CPU 的流水线被恢复为初始空状态,这样尚未在流水线中退出的指令无效,因此可以忽略。这使得 CPU 的设计更加困难。

进程和线程的区别在于进程切换(在所有主流操作系统中总是意味着线程切换)将需要更新内存转换信息、IO相关信息和权限相关结构。

这些将主要是指向更丰富的数据结构的指针,因此与线程上下文切换相关的成本不会很大。

于 2009-06-29T11:20:57.923 回答
2

在同一进程的线程间进行上下文切换时,保存当前线程的所有非易失性通用寄存器,恢复新线程的所有非易失性通用寄存器;仅当当前线程执行被中断中断时,才需要保存易失性寄存器。线程使用的任何协处理器(例如浮点处理器)的寄存器也应保存和恢复如果切换是在 2 个进程的线程之间,除了正常的上下文切换所需的之外,内存和 IO 管理相关也应该进行改变;例如,进程所需的内存保护是使用页表和页目录表实现的,每个进程都有一个唯一的页目录表地址,当进程更改时必须更改该地址。

于 2009-06-29T12:04:22.547 回答
1

这取决于您使用的操作系统,但可以肯定的是,您必须保存所有寄存器的内容(包括指令计数器)并加载您要切换到的线程的寄存器。

关于在同一进程上的两个线程之间切换,我想到的唯一区别是您不会丢失 L1 和 MMU 缓存的内容。

于 2009-06-29T11:03:18.660 回答
-3

我不确定,但如果我没记错的话,工作记忆集也会被切换。

于 2009-06-29T11:19:13.073 回答