我有这句话来自Goetz的 Java Concurrency In Practice :
由于上下文切换导致的线程运行时开销包括保存和恢复执行上下文,丢失局部性以及调度线程而不是运行它们所花费的CPU时间。
“失去地方”是什么意思?
答案 0 :(得分:9)
当线程工作时,它通常从内存和磁盘读取数据。数据通常存储在内存/磁盘上的连续或关闭位置(例如,在迭代数组时,或在读取对象的字段时)。硬件通过将内存块加载到快速缓存中来下注,以便更快地访问连续/关闭内存位置。
当您拥有大量线程并在它们之间切换时,通常需要刷新并重新加载这些缓存,这使得线程代码比一次执行所需的时间更长,而无需切换到其他线程并稍后再回来。
有点像我们人类在被打断后需要一些时间回到任务,找到我们在哪里,我们在做什么等等。
答案 1 :(得分:1)
只是详细说明JB Nizet所做的“缓存未命中”。
当一个线程在核心上运行时,它将最近使用的数据保存在核心本地的L1 / L2缓存中。现代处理器通常在大约5-7 ns内从L1 / L2高速缓存读取数据。
当暂停(从中断,等待队列等)线程再次运行时,它很可能会在不同的核心上运行。这意味着这个新核心的L1 / L2缓存没有与线程正在进行的工作相关的数据。它现在需要转到主存储器(大约需要100 ns)来加载数据才能继续工作。
有一些方法可以通过使用线程关联库将线程固定到特定核心来缓解此问题。