Performance 上下文切换有多贵?实现手动任务切换比依赖操作系统线程更好吗?

Performance 上下文切换有多贵?实现手动任务切换比依赖操作系统线程更好吗?,performance,context-switch,Performance,Context Switch,假设我有两个(三个,四个,随便什么)任务必须并行运行。现在,实现这一点的简单方法是创建单独的线程,然后忘记它。但是在一个普通的单核CPU上,这将意味着大量的上下文切换——我们都知道上下文切换是大的、坏的、慢的,而且通常是邪恶的。应该避免,对吗 在这方面,如果我从头开始编写软件,我可以更进一步,实现我自己的任务切换。将每个任务拆分为多个部分,在两个部分之间保存状态,然后在单个线程中在它们之间切换。或者,如果我检测到有多个CPU核,我可以将每个任务分配给一个单独的线程,这样一切都会很好 第二种解决方

假设我有两个(三个,四个,随便什么)任务必须并行运行。现在,实现这一点的简单方法是创建单独的线程,然后忘记它。但是在一个普通的单核CPU上,这将意味着大量的上下文切换——我们都知道上下文切换是大的、坏的、慢的,而且通常是邪恶的。应该避免,对吗

在这方面,如果我从头开始编写软件,我可以更进一步,实现我自己的任务切换。将每个任务拆分为多个部分,在两个部分之间保存状态,然后在单个线程中在它们之间切换。或者,如果我检测到有多个CPU核,我可以将每个任务分配给一个单独的线程,这样一切都会很好

第二种解决方案确实具有适应可用CPU内核数量的优势,但是手动任务切换真的会比OS内核中的更快吗?特别是如果我想用
TaskManager
ITask
等使整个事情变得通用

澄清:我是一名Windows开发人员,因此我主要对该操作系统的答案感兴趣,但了解其他操作系统也是最有趣的。当你写你的答案时,请说明它是针对哪个操作系统的

更多说明:好的,因此这不在特定应用程序的上下文中。这确实是一个一般性的问题,是我对可伸缩性思考的结果。如果我希望我的应用程序能够扩展并有效地利用未来的CPU(甚至是今天不同的CPU),我必须使它具有多线程。但是有多少线?如果线程数保持不变,那么程序将在所有内核数不相同的CPU上执行次优

理想情况下,线程的数量将在运行时确定,但很少有任务可以在运行时真正拆分为任意数量的部分。然而,许多任务可以在设计时分割成相当大的固定数量的线程。例如,如果我的程序可以产生32个线程,那么它已经使用了最多32个核心CPU的所有核心,这在未来还很遥远(我想)。但在一个简单的单核或双核CPU上,这将意味着大量的上下文切换,这将减慢速度

这就是我对手动任务切换的想法。通过这种方式,可以创建32个“虚拟”线程,这些线程将映射到尽可能多的实际线程,并且“上下文切换”将手动完成。问题是——我的手动“上下文切换”的开销会比操作系统上下文切换的开销小吗


当然,所有这些都适用于CPU受限的进程,比如游戏。对于一般的CRUD应用程序,这没有什么价值。这样的应用程序最好使用一个线程(最多两个线程)。

单核Windows机器将在未来几年内灭绝,因此我通常在编写新代码时假设多核是常见情况。我要说的是使用OS线程管理,它将自动处理硬件现在和将来提供的任何并发性


我不知道您的应用程序是做什么的,但除非您有多个绑定到计算的任务,否则我怀疑上下文切换在大多数应用程序中是否是一个重要的瓶颈。如果您的任务阻塞I/O,那么您将无法从尝试超越操作系统中获得太多好处。

我所看到的手动切换的唯一优点是,您可以更好地控制切换发生的位置和时间。理想的地方当然是在完成一个单元的工作之后,这样你就可以把它全部扔掉。这样可以避免缓存丢失


我建议不要把精力花在这上面。

我不认为手动任务切换会更快,因为操作系统内核仍在切换其他进程,包括您的进程也处于非运行状态。这似乎是一个过早的优化和潜在的巨大浪费

如果系统没有做任何其他事情,那么很可能你不会有大量的上下文切换。线程将使用它的时间片,内核调度程序将看到不需要运行其他任何东西,并直接切换回线程。此外,操作系统将尽最大努力避免在CPU之间移动线程,因此您可以从缓存中获益

如果您确实是CPU受限的,请检测CPU的数量并启动那么多线程。您应该看到几乎100%的CPU利用率。如果不是,那么您就没有完全的CPU限制,答案可能是启动N+X线程。对于非常受IO限制的进程,您将启动CPU数的(大)倍数(即高流量Web服务器运行1000多个线程)


最后,作为参考,Windows和Linux调度程序每毫秒都会唤醒一次,以检查是否需要运行另一个进程。因此,即使在空闲系统上,每秒也会看到1000多个上下文切换。在重负载系统上,我发现每个CPU每秒超过10000次,没有任何重大问题。

您对什么操作系统感兴趣?这在不同的操作系统中差异很大。我基本上是一个Windows程序员,但听其他操作系统的介绍也会很有趣。“我试图使这个问题变得相当不可知。”西蒙——真的吗?或者你的意思是答案不可能是操作系统不可知论的?用简单的方式写吧。在低端目标系统上测试代码。如果运行速度太慢,请对其进行配置。修理零件花费的时间太长。你写的是“从头开始”。您不知道上下文切换是否会成为您的瓶颈。@Vilx您在问上下文切换是否昂贵。如果不具体说明您所谈论的操作系统,这个问题就毫无意义。这有点像问一辆车是快还是房子大。没有指定哪辆车或哪栋房子就没有意义。当然,这只适用于CPU限制的进程。我不是故意的