multithreading - 上下文切换中保存了什么?

标签 multithreading memory context-switch

在两个线程之间的上下文切换中准确保存和恢复的内容

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

最佳答案

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

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

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

请注意,尝试只做与上下文切换相关的最小工作量是 topic of some academic interest

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

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

其中之一是“thread_struct”

/* CPU-specific state of this task */
- struct thread_struct thread;
holds information about cache TLS descriptors, debugging registers,
fault info, floating point, virtual 86 mode or IO permissions.

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

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

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

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

关于multithreading - 上下文切换中保存了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1057711/

相关文章:

Java:加快我的代码速度

c++ - 我怎样才能知道 C++ 类的一个实例消耗了多少内存?

gcc - LDMIA 指令在皮质 M4 的外部 SRAM 上无法正常工作

io - printf() 是否调用短期调度程序来调度就绪队列中的另一个进程?

Java Fork Join 池吃掉所有线程资源

c# - 当我们创建并启动一个新的 .NET 线程时,它会创建一个新的操作系统级线程吗?

java - 最小优先级线程如何在最大优先级线程之前执行?

php - 将数据库保存在内存中,即使客户端脚本断开连接

linux-kernel - CPU 在 X86 上从内核模式切换到用户模式 ​​: When and How?

c# - 我如何测量在进程上下文切换中花费的时间的近似值?