我一直在阅读关于冯诺依曼的瓶颈和 AFAIK,问题在于 CPU 应该获取或修改数据操作,但不能同时进行;因为它们都需要访问相同的内存总线。所以,问题主要在于有限的总线传输率。我已经读过如何缓解这个问题,它提到并行处理应该解决它,它不仅仅依赖于 1 个核心,所以当一个核心卡在 fetch 操作中时,其他核心以单独的方式工作大大减少了计算时间。
这是一个正确的理解吗?如果是这样,不是所有这些核心都共享相同的内存总线吗?哪个从一开始就成了瓶颈?
我一直在阅读关于冯诺依曼的瓶颈和 AFAIK,问题在于 CPU 应该获取或修改数据操作,但不能同时进行;因为它们都需要访问相同的内存总线。所以,问题主要在于有限的总线传输率。我已经读过如何缓解这个问题,它提到并行处理应该解决它,它不仅仅依赖于 1 个核心,所以当一个核心卡在 fetch 操作中时,其他核心以单独的方式工作大大减少了计算时间。
这是一个正确的理解吗?如果是这样,不是所有这些核心都共享相同的内存总线吗?哪个从一开始就成了瓶颈?
它没有。 冯诺依曼瓶颈是指处理器和内存位于慢速总线的相对两侧。如果你想计算一些东西,你必须通过总线将输入移动到处理器。然后,当计算完成时,您必须将输出存储到内存中。您的吞吐量受到内存总线速度的限制。
缓存通过将少量经常使用的数据保留在处理器附近,有助于缓解许多工作负载的这个问题。如果您的工作负载像许多人一样重用大量数据,那么您将从缓存中受益。但是,如果您正在处理的数据集太大而无法放入缓存中,或者您的算法没有很好的数据重用性,那么缓存可能不会带来太多好处。考虑处理一个非常大的数据集。您需要加载所有数据并至少将其存储一次。如果幸运的话,您的算法将只需要查看每个数据块一次,并且任何重用的值都将保留在缓存中。如果不是这样,您可能会在每个数据元素上不止一次地通过内存总线。
并行处理是一个相当广泛的术语。根据您的操作方式,您可能会或可能不会获得更多带宽。
今天实现共享内存处理器的方式根本无法解决冯诺依曼瓶颈问题。如果有的话,拥有更多内核会给总线带来更大的压力,因为现在有更多的处理器需要从内存中获取数据。您将需要更多带宽来满足所有这些需求。恰当的例子:许多并行算法是受内存限制的,它们无法利用现代多核芯片上的所有内核,特别是因为它们无法足够快地获取数据。核心数量正在增加,并且每个核心的带宽可能会在限制范围内减少,即使总带宽从处理器到处理器的增加也是如此。
现代内存总线变得越来越复杂,你可以做一些事情来更有效地使用它们。例如,在NUMA机器上,一些内存库比其他的更靠近一些处理器,如果你有效地布局数据,你可以获得比盲目地从 RAM 中的任何地方获取更多的带宽。但是,扩展共享内存很困难——请参阅分布式共享内存机器,了解为什么很难将共享内存机器扩展到几千个内核。
分布式内存机器是一种并行机器。这些通常被称为集群——它们基本上只是同一网络上的一堆节点,它们试图完成一项共同的任务。如果每个处理器仅从其本地内存中获取,您可以在集群中获得线性带宽扩展。但是,这需要您有效地布置数据,以便每个处理器都有自己的块。人们称之为数据并行计算。如果您的数据大部分是数据并行的,您可能可以使用大量处理器,并且可以并行使用所有内存带宽。如果你不能并行化你的工作负载,或者如果你不能将数据分成块以便每个块主要由一个或几个节点处理,那么你又回到了顺序工作负载,你仍然受到带宽的约束单核。
人们已经研究了替代节点架构来解决冯诺依曼瓶颈。最常被引用的可能是Processor-in-memory或PIM。在这些架构中,为了解决内存总线问题,您在内存中嵌入了一些处理器,有点像集群,但规模较小。每个微小的核心通常可以对其本地数据执行一些不同的算术运算,因此您可以非常快速地执行一些操作。同样,虽然很难以一种实际上使这种类型的处理有用的方式布置数据,但是一些算法可以利用它。
总而言之,通用计算机中的冯诺依曼瓶颈(处理器可以对来自内存中任何地址的数据执行任何操作)来自这样一个事实,即您必须将数据移动到处理器才能计算任何东西。
简单地构建一个并行机器并不能解决问题,特别是如果你所有的内核都在内存总线的同一侧。如果您愿意拥有许多处理器并将它们分散开,以便它们比其他数据更接近某些数据,那么您可以利用数据并行性来获得更多带宽。但是,集群和 PIM 系统比单核 CPU 更难编程,而且并不是每个问题都从根本上是数据并行的。所以冯诺依曼瓶颈很可能会伴随我们一段时间。
冯诺依曼瓶颈来自代码和数据的共享内存总线。如果您忽略当今处理器的复杂功能,并想象一个带有一些 RAM 和一些闪存的简单 8 位冯诺依曼处理器,处理器会不断地被迫等待 RAM 操作完成,然后再从闪存加载更多数据。如今,缓解措施主要通过处理器的 L1 和 L2 缓存以及嵌入在处理器中的分支预测逻辑来完成。指令可以预加载到缓存中,内存总线可以自由使用。并行化可以帮助解决特定的工作负载,但现实情况是,今天的计算范式并没有真正受到这个瓶颈的太大影响。处理器非常强大,内存和总线非常快,如果您需要更高的吞吐量,您可以向处理器添加更多缓存(就像英特尔对 Xeons 所做的那样,以及 AMD 对 Opterons 所做的那样)。并行化更多地也是一种回避问题的方法,您的并行工作负载仍然受制于处理器架构施加的相同规则。如果有的话,多线程应该会使问题变得更糟,因为多个工作负载竞争相同的内存总线。同样,解决方案只是在内存总线和处理器内核之间添加更多缓存。
随着内存越来越快,处理器不再那么快,我们可能会看到这个问题再次成为一个问题。但是鸟儿们说生物计算机是通用计算的未来,所以希望下一个主要架构能够考虑过去的错误。