线程上下文切换与进程上下文切换

有没有人能告诉我在这两种情况下到底要做什么? 每种情况的主要成本是什么?

107616 次浏览

简而言之,线程上下文切换不会分配一组全新的内存和 pid,它使用与父进程相同的内存和 pid,因为它在相同的进程中运行。一个进程生成一个新的进程,从而分配新的 mem 和 pid。

还有一件事,他们已经就此写了书。

至于成本,一个进程上下文切换 > > > > 线程,因为你必须重置所有的堆栈计数器等。

线程切换和进程切换之间的主要区别在于,在线程切换期间,虚拟内存空间保持不变,而在进程切换期间,虚拟内存空间不变。 这两种类型都涉及将控制权移交给操作系统内核来执行上下文切换。切换进出 OS 内核的过程以及切换寄存器的成本是执行上下文切换的最大固定成本。

更模糊的代价是上下文切换会干扰处理器缓存机制。基本上,当您进行上下文切换时,处理器在其缓存中“记忆”的所有内存地址实际上都变得毫无用处。这里最大的区别在于,当您更改虚拟内存空间时,处理器的转译后备缓冲器(TLB)或等价物会被刷新,使内存访问在一段时间内变得昂贵得多。在线程切换期间不会发生这种情况。

假设操作系统运行的 CPU 附加了一些高延迟设备,

当高延迟设备响应时,运行进程地址空间的另一个线程是有意义的。

但是,如果高延迟设备的响应速度快于需要为一个新进程设置表 + 转换虚拟物理存储器的时间,那么如果一个开关是必不可少的,这是值得怀疑的。

另外,HOT 缓存(运行进程/线程所需的数据可以在更短的时间内获得)是更好的选择。

  • 进程切换: 它是多道程序设计环境中进程的两个驻留内存之间的转换;
  • 上下文切换: 这是一个从正在执行的程序到 interrupt handler (ISR)的上下文切换。

进程上下文切换包括切换内存地址空间。这包括内存地址、映射、页表和内核资源ーー这是一种相对昂贵的操作。在某些架构中,它甚至意味着刷新不能跨地址空间共享的各种处理器缓存。例如,x86必须刷新 TLB,而一些 ARM 处理器必须刷新整个 L1缓存!

线程切换是在同一进程中从一个线程切换到另一个线程的上下文切换(跨进程从一个线程切换到另一个线程只是进程切换)。切换处理器状态(例如程序计数器和寄存器内容)通常是非常有效的。

首先,操作系统会在内核模式下引入传出线程(如果它还不存在的话) ,因为线程切换只能在运行在内核模式下的线程之间执行。然后调用调度程序来决定将执行切换到哪个线程。在做出决定之后,内核将位于 CPU (CPU 寄存器)中的部分线程上下文保存到内存中的专用位置(通常位于外出线程的内核堆栈的顶部)。然后内核执行从输出线程的内核堆栈到输入线程的内核堆栈的切换。然后,内核将以前存储的从内存传入线程的上下文加载到 CPU 寄存器中。最后将控制返回到用户模式,但是处于新线程的用户模式。 在操作系统确定传入线程在 另一个进程中运行的情况下,内核执行一个额外的步骤: 设置新的活动虚拟地址空间。

这两种情况下的主要成本都与缓存污染有关。在大多数情况下,传出线程使用的工作集将与传入线程使用的工作集大不相同。因此,传入的线程将在大量缓存丢失的情况下开始其生命周期,从而刷新缓存中的旧数据和无用数据,并从内存中加载新数据。对于 TLB (位于 CPU 上的翻译查看旁边的缓冲区)也是如此。在虚拟地址空间重置(线程运行在不同的进程中)的情况下,代价更大,因为虚拟地址空间的重置导致整个 TLB、 甚至的刷新,如果新线程实际上只需要加载很少的新条目。因此,新线程将开始它的时间量,许多 TLB 缺失和频繁的页面遍历。线程切换的直接成本也不可忽视(从约250到约1500-2000个周期) ,并取决于 CPU 的复杂性,线程的状态和它们实际使用的寄存器集。

附注: 关于上下文切换开销的好帖子: http://blog.tsunanet.net/2010/11/how-long-does-it-take-to-make-context.html

在线程上下文切换中,虚拟内存空间保持不变,而在进程上下文切换中则不保持不变。此外,进程上下文切换比线程上下文切换更昂贵。

我认为主要区别在于调用 switch_mm()时,它处理新旧任务的内存描述符。在线程的情况下,虚拟内存地址空间是不变的(线程共享虚拟内存) ,因此需要做的事情很少,因此成本较低。

虽然线程上下文切换需要更改执行上下文(寄存器、堆栈指针、程序计数器) ,但它们不需要像进程上下文切换那样更改地址空间。切换地址空间、更多内存访问(分页、分段等)以及在进入或退出新进程时必须刷新 TLB 时,会产生额外的成本..。