多 CPU 是第一个版本:您将拥有一个或多个主板,上面有一个或多个 CPU 芯片。这里的主要问题是 CPU 必须将它们的一些内部数据暴露给另一个 CPU,这样它们就不会妨碍它们。
下一步是超线程。主板上的一个芯片,但它内部有一些部件两次,因此它可以同时执行两条指令。
目前的发展是多核。它基本上是最初的想法(几个完整的 CPU),但在一个芯片中。优势:芯片设计人员可以轻松地将同步信号的附加线放入芯片中(而不必将它们布线在一个引脚上,然后穿过拥挤的主板并向上进入第二个芯片)。
今天的超级计算机是多 CPU、多核的:它们有很多主板,上面通常有 2-4 个 CPU,每个 CPU 都是多核的,每个 CPU 都有自己的 RAM。
[编辑] 你说得很对。只是几个小点:
超线程在单个内核中同时跟踪两个上下文,从而为乱序 CPU 内核提供更多并行性。即使一个线程因缓存未命中、分支错误预测或等待高延迟指令的结果而停滞,这也可以使执行单元保持工作。这是一种无需复制太多硬件即可获得更多总吞吐量的方法,但如果有的话,它会单独减慢每个线程。 有关更多详细信息,请参阅此问答,以及对本段先前措辞的错误解释。
多 CPU 的主要问题是在它们上运行的代码最终会访问 RAM。有 N 个 CPU,但只有一条总线可以访问 RAM。所以你必须有一些硬件来确保 a) 每个 CPU 获得相当数量的 RAM 访问,b) 访问 RAM 的同一部分不会导致问题,c) 最重要的是,CPU 2 将被通知当 CPU 1 写入 CPU 2 在其内部缓存中的某个内存地址时。如果这没有发生,CPU 2 将愉快地使用缓存的值,而不会注意到它已经过时的事实
想象一下,您有一个列表中的任务,并且您想将它们分散到所有可用的 CPU 上。因此 CPU 1 将从列表中获取第一个元素并更新指针。CPU 2 也会这样做。出于效率原因,两个 CPU 不仅会将少数字节复制到缓存中,还会复制整个“缓存行”(无论是什么)。假设是,当您读取字节 X 时,您很快也会读取 X+1。
现在两个 CPU 在它们的缓存中都有一份内存副本。然后 CPU 1 将从列表中获取下一个项目。如果没有缓存同步,它不会注意到 CPU 2 也更改了列表,并且它将开始与 CPU 2 处理相同的项目。
这就是有效地使多 CPU 如此复杂的原因。这样做的副作用可能会导致性能比整个代码仅在单个 CPU 上运行时所获得的性能更差。解决方案是多核的:您可以轻松添加任意数量的线来同步缓存;您甚至可以将数据从一个缓存复制到另一个(更新缓存行的一部分而无需刷新和重新加载它)等。或者缓存逻辑可以确保所有 CPU 在访问同一部分时获得相同的缓存行真正的 RAM,只是阻塞 CPU 2 几纳秒,直到 CPU 1 做出改变。
[EDIT2] 多核比多 CPU 更简单的主要原因是在主板上,您根本无法在两个芯片之间运行所有需要使同步有效的线路。再加上一个信号只能传播 30 厘米/纳秒的顶部(光速;在电线中,你通常会少得多)。并且不要忘记,在多层主板上,信号开始相互影响(串扰)。我们喜欢认为 0 是 0V,1 是 5V,但实际上,“0”是介于 -0.5V(从 1->0 下降线时过驱动)和 0.5V 之间的值,而“1”是高于 0.8V 的任何值。
如果您将所有东西都放在一个芯片中,则信号运行速度会更快,并且您可以拥有任意数量的信号(嗯,几乎 :)。此外,信号串扰更容易控制。