Answers:
线程切换与进程切换之间的主要区别在于,在线程切换期间,虚拟内存空间保持不变,而在进程切换期间则不相同。两种类型都涉及将控制权移交给操作系统内核以执行上下文切换。切入和切出OS内核的过程以及切出寄存器的成本是执行上下文切换的最大固定成本。
更为模糊的代价是上下文切换使处理器缓存机制混乱。基本上,当您进行上下文切换时,处理器在其缓存中“记住”的所有内存地址实际上都变得无用。这里的一大区别是,当您更改虚拟内存空间时,会清空处理器的转换后备缓冲区(TLB)或等效的缓冲区,从而使内存访问花费更多时间。在线程切换期间不会发生这种情况。
进程上下文切换涉及切换内存地址空间。这包括内存地址,映射,页表和内核资源,这是一个相对昂贵的操作。在某些体系结构上,这甚至意味着刷新无法跨地址空间共享的各种处理器缓存。例如,x86必须刷新TLB,而某些ARM处理器必须刷新整个L1缓存!
线程切换是在同一进程中从一个线程到另一个线程的上下文切换(跨进程的从一个线程到另一个线程的切换只是进程切换)。切换处理器状态(例如程序计数器和寄存器内容)通常非常有效。
首先,如果操作系统尚未将传出线程放入内核模式,则该操作系统会将其置于内核模式,因为线程切换只能在以内核模式运行的线程之间执行。然后,调用调度程序以决定要切换到的线程。做出决定后,内核将位于CPU(CPU寄存器)中的部分线程上下文保存到内存中的专用位置(通常位于传出线程的内核堆栈的顶部)。然后,内核执行从输出线程的内核堆栈到输入线程的内核堆栈的切换。之后,内核将先前存储的传入线程上下文从内存加载到CPU寄存器中。最后,将控制权返回到用户模式,但处于新线程的用户模式。如果OS确定传入线程在其中运行在另一个过程中,内核执行一个附加步骤:设置新的活动虚拟地址空间。
两种情况下的主要成本都与缓存污染有关。在大多数情况下,传出线程使用的工作集与传入线程使用的工作集会有很大不同。结果,传入线程将以大量的高速缓存未命中来开始其生命,从而从高速缓存中清除旧的和无用的数据,并从内存中加载新数据。对于TLB(转换后备缓冲区,它在CPU上)也是如此。在重置虚拟地址空间(线程在不同进程中运行)的情况下,代价甚至更糟,因为重置虚拟地址空间会导致整个TLB的刷新,甚至如果新线程实际上只需要加载几个新条目。结果,新线程将以很多TLB丢失和频繁的页面遍历开始其时间范围。线程切换的直接成本也是不可忽略的(从〜250个周期到大约1500-2000个周期),并且取决于CPU复杂性,线程的状态以及它们实际使用的寄存器集。
PS:关于上下文切换开销的好帖子:http : //blog.tsunanet.net/2010/11/how-long-does-it-take-to-make-context.html