想象一下,我有两个(三个、四个,等等)必须并行运行的任务。现在,执行此操作的简单方法是创建单独的线程并忘记它。但是在一个普通的老式单核 CPU 上,这意味着很多上下文切换——我们都知道上下文切换很大、很糟糕、很慢,而且通常只是邪恶的。应该避免吧?
在那一点上,如果我是从头开始编写软件,我可以加倍努力并实现我自己的任务切换。将每个任务分成几部分,保存中间的状态,然后在单个线程中切换它们。或者,如果我检测到有多个 CPU 内核,我可以将每个任务分配给一个单独的线程,一切都会好起来的。
第二种解决方案确实具有适应可用 CPU 内核数量的优势,但是手动任务切换真的会比 OS 内核中的更快吗?特别是如果我试图用 aTaskManager
和 anITask
等使整个事情通用?
澄清:我是一名 Windows 开发人员,所以我主要对这个操作系统的答案感兴趣,但最有趣的是找出其他操作系统。当您写下您的答案时,请说明它适用于哪个操作系统。
更多说明:好的,所以这不是在特定应用程序的上下文中。这确实是一个普遍的问题,是我对可扩展性的思考的结果。如果我希望我的应用程序能够扩展并有效地利用未来的 CPU(甚至是今天的不同 CPU),我必须让它成为多线程的。但是有多少线程?如果我创建恒定数量的线程,那么程序将在所有内核数不同的 CPU 上执行次优。
理想情况下,线程数将在运行时确定,但很少有任务可以在运行时真正拆分为任意数量的部分。然而,许多任务可以在设计时拆分为相当大的恒定数量的线程。因此,例如,如果我的程序可以产生 32 个线程,那么它已经使用了多达 32 核 CPU 的所有内核,这在未来还很遥远(我认为)。但是在一个简单的单核或双核 CPU 上,这将意味着大量的上下文切换,这会减慢速度。
因此,我对手动任务切换的想法。这样一来,可以创建 32 个“虚拟”线程,这些线程将映射到尽可能多的真实线程,并且“上下文切换”将手动完成。问题只是 - 我的手动“上下文切换”的开销会小于操作系统上下文切换的开销吗?
自然,所有这些都适用于受 CPU 限制的进程,例如游戏。对于您的普通 CRUD 应用程序,这几乎没有价值。这样的应用程序最好使用一个线程(最多两个)。