为什么没有强制使用多核的软件?

Why aren't there any software that force the use of multiple cores?

所以这是一个纯假设性的问题。我必须首先提出一个免责声明:我完全不知道处理器是如何在低层次上工作的,甚至是在高层次上,但是低层次和高层次的解释是值得赞赏的,因为我仍然可以围绕答案(可能需要我几个小时)。

所以问题是:为什么会有软件不能利用多核或多线程的优势? 或者更好的措辞,为什么必须在软件中对多线程支持进行编码,并且处理器不会自动分配给所有内核,而不管代码如何?

我非常天真的看待它的方式是软件会请求 CPU 进行一些计算,那么为什么 CPU 不能有一个 "master thread",它确实只是将计算分配给其他每个线程,然后将结果转发回软件?

因为我知道很多软件一次只能使用一个内核,而且根据我对 CPU 工作原理的天真理解,不应该有理由阻止它发送对所有可用内核的计算。

关于这一点,主要问题:是否有可能创建一个软件(或驱动程序),使任何软件都可以使用所有可用的内核,而不管它是如何使用的编码?

so why can't the CPU have a "master thread", which does nothing but assign the calculations to each of the other threads, and then forward the result back to the software as they come?

您提到这一点实际上很有趣,因为它是某种 高性能CPU 的工作方式。尽管在 "some code that's running and doing that distribution" 的意义上没有实际的线程,但硬件本身将指令(或部分指令,对于复杂指令)分布在多个功能单元上。这是一个非常细粒度的并行性级别,称为指令级并行性,它在现代 CPUs 的速度方面起着重要作用,并且与其他形式的并行性不同,它可以自动提取。这种情况发生的程度主要受代码中可提取并行性的可用性以及 CPU 提取它的能力的限制。

多(真实)内核是此类内部并行内核的多个副本,并行之上的并行。超线程(和类似的 SMT 实现)使用内部并行性来模拟多个内核,这通常可以提高实际内核的利用率,在某种意义上与您描述的相反。

On that note, the main question: Is it possible to create a software (or driver) which enables ANY software to use all available cores, regardless of how it has been coded?

不对,同理两个女人四个半月不能生孩子。

计算是数据的转换,从输入到输出,每一步读取它需要的数据并产生结果。
很明显,这意味着步骤之间存在依赖关系: (x + 1)^2 对于 x = 3 是 16 但是要得到这个结果我们首先执行步骤 y = x + 1 然后执行步骤 y^2.
我们无法在 (y)^2 之前甚至同时计算 x + 1 以获得正确的结果。

简而言之,并非所有东西都是可并行化的

CPU,正如 Harold 指出的那样,可以利用某些计算的内在并行性:(x + 1) + (x + 2) 可以拆分并行计算 y = ( x + 1)z = (x + 2) 和然后做 y + z.
这都是关于计算的 依赖链

这一优化的难点在于,与这些示例相反,指令通常有副作用,必须非常小心地考虑到它们。
如今,大多数努力都用于快速预测何时允许正常 禁止 优化,预测大部分时间但并非所有时间都是准确的,并从错误预测中快速恢复。 此外,在查找或跟踪这些优化时,可用资源是有限的。

所有这些逻辑都被打包到一个核心中,它以利用内在并行性的方式获取、解码、发布、分派、执行和退出指令。

即使有了这个帮助,核心的功能单元通常比程序可用的功能单元多,例如,这可能是由于仅使用整数。 此外,由于现代 CPU 非常复杂,因此充分利用它们也很复杂。
这就是引入 SMT(即每个核心中的两个线程)的原因:每个线程都有自己的程序(上下文),但共享核心中的所有其他资源,当一个程序使用整数时,另一个使用浮点数可以使 CPU 完全使用。

但是每个线程都有其 context,就像每个线程都有自己的 xy, z.
如果我们在 Core0 中计算 y = (x + 1) 我们不能将 y^2 发送到 Core1 因为 y 使用的将是 Core1 中的那个,因此是错误的。
因此,要使程序并行化,就必须进行人为干预,将单个程序分成两个或更多个。 将 y^2 发送到 Core1 还需要发送 y,这会 太慢,原因如下.

当添加另一个核心的成本低于进一步优化核心微架构的成本时,制造商开始包括多个核心。

为什么不能将用于利用内在并行性的机制扩展为将指令分派给多个 cores/threads?
因为,电子化是不可能的。
为了让它工作,必须有一个共享的上下文(变量集xy,...)并且有一个单一的上下文被很多内核访问会使它变慢。
理解起来可能不直观,但在 16 个目的地之间进行选择比在 32 个目的地之间进行选择更快。管理 4 个阅读器而不是 16 个阅读器时也是如此。
此外,在现代 CPU 的速度下,轨迹的几何形状 非常重要

所以核心设计得很快,有快速的内部总线和快速紧密耦合的组件,它们或多或少地以相同的频率工作。
CPU uncore 被设计为尽可能快,在内核和以不同频率工作的其他组件之间快速解耦。

简而言之,将指令分派给其他内核会很慢,内核之间的通信比通信慢一个数量级intra-core。
对于一般用途 CPUs 不方便用程序发送数据。
让程序员 编程 每个 core/thread 单独并在需要时交换所需的数据会更高效。

对于特定用途,ASIC 可能会采用不同的方法,例如,GPU 的并行性与 CPUs 不同。