为什么没有任何软件可以强制使用多个内核?

时间:2019-08-30 10:54:02

标签: multithreading cpu core

这是一个纯粹的假设问题。首先,我必须声明一个免责声明:从字面上我不知道处理器在低水平甚至高水平上是如何工作的,但是可以理解低水平和高水平的解释,因为我仍然可以将答案包裹住(也许要花我几个小时)。

问题是:为什么会有一些软件无法利用多个内核或线程? 还是更好的措辞,为什么必须在软件中编写多线程支持,并且不管代码是什么,处理器都不会自动将其分配给所有内核吗?

我非常天真的看待方式是该软件将请求CPU进行一些计算,所以为什么CPU不能有一个“主线程”,该主线程除了将计算分配给其他每个线程外什么也不做,然后将结果转发回软件中?

因为我知道很多软件一次只能使用一个内核,并且从我对CPU工作原理的幼稚理解中,没有理由阻止它仅将计算发送到所有可用内核。

关于该问题,主要问题:是否可以创建一个软件(或驱动程序),使任何软件都可以使用所有可用的内核,而无论其编码方式如何?

2 个答案:

答案 0 :(得分:0)

  

那么,为什么CPU不能有一个“主线程”,该主线程除了将计算分配给其他每个线程之外什么也不做,然后将结果转发给软件,又将其转发回软件?

您提到这一点实际上很有趣,因为这是高性能CPU的工作原理。尽管“硬件正在将指令(或指令的一部分,对于复杂指令而言)”分布在多个功能单元上,但是在“正在运行并进行该分配的某些代码”的意义上,并没有实际的线程。这是一个非常细粒度的并行性,称为指令级并行性,它在现代CPU的运行速度方面起着重要作用,并且与其他形式的并行性不同,它可以自动提取。发生这种情况的程度主要受代码中可提取并行性的可用性以及CPU提取它的能力的限制。

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

答案 1 :(得分:0)

  

注意,主要问题是:是否有可能创建一个软件(或驱动程序),使任何软件都可以使用所有可用的内核,而无论其编码方式如何?

不,出于同样的原因,两个女人无法在四个半月内分娩。

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

简而言之,并非所有事物都是可并行化的

正如Harold指出的那样,

CPU可以利用某些计算的内在并行性:(x + 1)+(x + 2)可以分解为计算 y =(x + 1) z =(x + 2) ,然后执行 y + z
这都是关于计算的依赖链

此优化的难点在于,与这些示例相反,这些说明通常具有副作用,因此必须非常小心地将它们考虑在内。
当今,大多数工作都在快速预测何时允许通常禁止的优化,最准确但并非所有时间的预测,以及从错误预测中快速恢复。 此外,这是对寻找或跟踪这些优化时可用资源的限制。

所有这些逻辑都封装在一个内核中,它以一种利用固有并行性的方式来获取,解码,发出,调度,执行和退出指令。

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

但是每个线程都有它的 context ,就像每个线程都有它自己的 x y z 值一样。 em>。
如果我们在Core0中计算 y =(x + 1),则无法将 y ^ 2 发送到Core1,因为使用的 y 将是Core1,因此是错误的。
从而使程序并行化,需要人工干预才能将一个程序拆分为两个或更多。 将 y ^ 2 发送到Core1还需要发送 y ,这会太慢
,这就是为什么。

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

为什么不能扩展用于利用固有并行性的机制以将指令调度到多个内核/线程?
因为电子上是不可能的。
为了使其正常工作,必须有一个共享的上下文(变量 x y ,...的集合),并且有很多内核会使它变慢。
可能不容易理解,但是在16个目的地之间进行选择比在32个目的地之间进行选择要快。管理4个阅读器而不是16个阅读器时也是如此。
此外,在现代CPU的速度下,轨迹的几何非常重要

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

简而言之,向其他内核分配指令会很慢,内核之间的通信要比内核内部的通信慢几个数量级。
对于通用CPU,使用程序发送数据并不方便。
让程序员分别对每个内核/线程进行 program 并在需要时交换所需的数据,性能更高。

出于特定目的,ASIC可能采用不同的方法,例如GPU与CPU的并行度不同。