线程上下文切换与进程上下文切换
有谁能告诉我在这两种情况下究竟做了什么? 他们每个人的主要成本是多less?
线程切换与进程切换的主要区别在于,在进行线程切换时,虚拟内存空间保持不变,而在进程切换过程中,虚拟内存空间不变。 这两种types都涉及将控制交给操作系统内核来执行上下文切换。 切换进出操作系统内核的过程以及切换寄存器的成本是执行上下文切换的最大固定成本。
更加模糊的成本是上下文切换与处理器caching机制混淆。 基本上,当你进行上下文切换的时候,处理器在caching中“记住”的所有内存地址都是无用的。 这里最大的一个区别就是当你改变虚拟内存空间时,处理器的翻译后备缓冲区(TLB)或者等价物会被刷新,使内存访问在一段时间内变得更加昂贵。 这在线程切换期间不会发生。
进程上下文切换涉及切换内存地址空间。 这包括内存地址,映射,页表和内核资源 – 一个相对昂贵的操作。 在某些体系结构中,它甚至意味着冲洗不能跨地址空间共享的各种处理器高速caching。 例如,x86必须刷新TLB,一些ARM处理器必须刷新整个L1caching!
线程切换是在同一个进程中从一个线程切换到另一个线程的切换(在线程之间切换只是进程切换)。切换处理器状态(例如程序计数器和寄存器内容)通常非常有效。
- 进程切换:它是多进程环境中进程的两个内存驻留的转换;
- 上下文切换:从执行程序到中断服务程序(ISR)的变化。
首先,如果操作系统不在线,那么操作系统会把内核模式带出内核模式,因为线程切换只能在内核模式下运行的线程之间执行。 然后,调度程序被调用来决定执行切换的线程。 在做出决定之后,内核将位于CPU(cpu寄存器)中的线程上下文的一部分保存到内存中的专用位置(经常位于传出线程的内核堆栈顶部)。 然后内核执行从传出线程的内核栈切换到传入线程的内核栈。 之后,内核将之前存储的传入线程的上下文从内存加载到CPU寄存器中。 最后,将控制返回到用户模式,但在新线程的用户模式下。 在OS确定传入线程在另一个进程中运行的情况下,内核执行一个附加步骤:设置新的活动虚拟地址空间。
两种情况下的主要成本都与caching污染有关。 在大多数情况下,传出线程使用的工作集与传入线程使用的工作集有很大的不同。 因此,传入的线程将以雪崩的高速caching未命中的状态开始其生命,从而从caching中清除旧的和无用的数据,并从内存中加载新的数据。 TLB也是如此。 在虚拟地址空间复位(线程在不同进程中运行)的情况下,惩罚更加严重,因为虚拟地址空间的复位导致了TLB的清空。 令人难过的是,即使新线程实际上只需要加载很less的新条目,整个TLB也会被刷新。 结果,新的线程将开始它的时间与TLB失误和频繁页面行走。 线程切换的直接开销也是不可忽略的(从大约250到大约1500-2000个周期),取决于CPU的复杂性,它们实际使用的线程和寄存器组的状态。
PS:关于上下文切换开销的好post: http : //blog.tsunanet.net/2010/11/how-long-does-it-take-to-make-context.html
简而言之,线程上下文切换不会分配一组全新的内存和pid,因为它在同一个进程中运行,所以它与父进程使用相同。 一个进程产生一个新的进程,从而分配新的内存和PID。
还有一个loooooot更多。 他们已经写了书。
至于成本,一个进程上下文切换>>>>线程,因为你必须重置所有的堆栈计数器等
假设OS运行的CPU已经连接了一些高延迟设备,
运行进程的地址空间中的另一个线程是有意义的,而高延迟设备则回应。
但是,如果高延迟设备的响应速度快于需要为新进程build立虚拟到物理存储器的表+转换的时间,那么切换是否必不可less是有问题的。
此外,HOTcaching(运行进程/线程所需的数据可以在更短的时间内到达)是更好的select。