【问题标题】:Why aren't there any software that force the use of multiple cores?为什么没有强制使用多核的软件?
【发布时间】:2020-01-03 15:06:59
【问题描述】:

所以这是一个纯粹的假设问题。我必须首先提出一个免责声明:我实际上不知道处理器如何在低级别甚至高级别上工作,但是感谢低级别和高级解释,因为我仍然可以围绕答案(可能要花我几个小时)。

所以问题是:为什么会有软件不能利用多核或多线程? 或者更好的措辞,为什么必须在软件中编码多线程支持,而不考虑代码,处理器会自动分配给它的所有内核吗?

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

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

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

【问题讨论】:

  • 我相信不是。如果可能的话,我们今天会有这样的软件。 ;) 为该用例设计和编写了一个使用多个内核的程序。即使有可能,创建这样的软件也没有任何意义,因为在线程之间切换会耗费时间并因此而耗费性能。因此,如果单线程或多线程解决方案的性能更好或更差,则必须在每种情况下对其进行分析。
  • 程序中使用的算法与您在厨房中使用的食谱相比非常好。绝大多数描述了必须按顺序执行的顺序步骤。不这样做会使厨房变得一团糟,就像它会使程序变得一团糟一样,你不能在将面粉放入碗中的同时打破鸡蛋。然而,两名厨师通常可以同时制作两份不同的饭菜,只要他们协商使用烤箱即可。或者在他们之间分担主菜和甜点的工作。这也是编程中使用的实际并行性。

标签: multithreading cpu core


【解决方案1】:

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

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

计算是数据的转换,从输入到输出,每一步都读取所需的数据并产生结果。
很明显,这意味着步骤之间存在依赖关系: (x + 1)^2 for x = 3 是 16,但要得到这个结果,我们首先执行步骤 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,就像每个线程都有自己的xyz值em>.
如果我们在 Core0 中计算 y = (x + 1),我们无法将 y^2 发送到 Core1,因为使用的 y 将是Core1,因此是错误的。
因此,为了使程序并行化,有必要人工干预将单个程序分成两个或更多。 将 y^2 发送到 Core1 也需要发送 y,这会太慢,原因如下。

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

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

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

简而言之,将指令分派到其他内核会很慢,内核之间的通信比内核内通信慢一个数量级。
对于通用 CPU,不方便通过程序发送数据。
让程序员单独编程每个内核/线程并在需要时交换所需的数据,这样的性能会更高。

针对特定目的,ASIC 可能会采用不同的方法,例如 GPU 与 CPU 具有不同的并行度。

【讨论】:

    【解决方案2】:

    那么为什么 CPU 不能有一个“主线程”,它只会将计算分配给其他每个线程,然后在它们到来时将结果转发回软件?

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

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

    【讨论】:

    • 那么,当你有 16C/32T 的时候,为什么有些软件被限制在 1-2 个内核?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-15
    • 1970-01-01
    相关资源
    最近更新 更多