Parallel processing 一次只能有一个CPU访问RAM吗?

Parallel processing 一次只能有一个CPU访问RAM吗?,parallel-processing,computer-architecture,Parallel Processing,Computer Architecture,我目前正在尝试使用多核编程。我想用C++/Python/Java编写/实现一个并行矩阵乘法(我想Java将是最简单的一个) 但有一个问题我自己无法回答,那就是RAM访问如何与多个CPU协同工作 我的想法 我们有两个矩阵A和B。我们要计算C=A*B: 只有当n、m或p较大时,并行执行才会更快。假设n,m和p>=10000。为了简单起见,假设n=m=p=10000=10^4 我们知道,我们可以计算每个$c{i,j}$,而不看c的其他条目。因此,我们可以并行计算每个c{i,j}: 但是所有的c{1

我目前正在尝试使用多核编程。我想用C++/Python/Java编写/实现一个并行矩阵乘法(我想Java将是最简单的一个)

但有一个问题我自己无法回答,那就是RAM访问如何与多个CPU协同工作

我的想法 我们有两个矩阵A和B。我们要计算C=A*B:

只有当n、m或p较大时,并行执行才会更快。假设n,m和p>=10000。为了简单起见,假设n=m=p=10000=10^4

我们知道,我们可以计算每个$c{i,j}$,而不看c的其他条目。因此,我们可以并行计算每个c{i,j}:

但是所有的c{1,i}(i\in1,…,p)都需要A的第一行。因为A是一个有10^8个双精度的数组,它需要800MB。这绝对比CPU缓存大。但是一行(80kB)可以放入CPU缓存。所以我想把C的每一行都分配给一个CPU是个好主意(只要一个CPU空闲)。因此,这个CPU的缓存中至少会有一个内存,并从中受益

我的问题 如何管理不同内核(在普通英特尔笔记本电脑上)的RAM访问

我想必须有一个“控制器”,一次只能访问一个CPU。此控制器是否有特殊名称

碰巧,两个或多个CPU可能需要相同的信息。他们能同时拿到吗?RAM访问是矩阵乘法问题的瓶颈吗


当你知道一些介绍多核编程(C++/Python/Java)的好书时,请告诉我。

你应该以缓存友好的方式将并行化矩阵乘法的问题分开(有很多方法-搜索“平铺”。),从多个内核如何共享对某些资源(如共享缓存和内存)的访问的问题。第一个是指如何避免缓存抖动并实现数据的有效重用(在给定的缓存层次结构上),第二个是指内存带宽利用率。这两者确实是相互连接的,但它们大多是互斥的,因为良好的缓存会减少出站带宽(当然,这对性能和电源都是可取的)。然而,有时在数据不可重用或算法无法修改以适应缓存的情况下,这是无法做到的。在这些情况下,内存BW可能会成为您的瓶颈,不同的内核将不得不尽可能地共享它

大多数现代CPU都有多个内核共享一个最后一级缓存(我不确定在某些智能手机领域是这样,但对于笔记本电脑/台式机/服务器,这通常适用)。该高速缓存反过来与内存控制器进行通信(该控制器以前位于另一个名为north bridge的芯片上,但几年前已集成到大多数CPU中以实现更快的访问)。 通过内存控制器,整个CPU可以与DRAM对话,并告诉它取什么。MC通常足够聪明,可以组合访问,这样它们只需要最少的时间和精力来获取(请记住,从DRAM获取“页面”是一项很长的任务,通常需要首先取出缓冲在检测放大器中的当前页面)

请注意,这种结构意味着MC不必单独与多个内核通信,它只需将数据获取到最后一级缓存。内核也不需要直接与内存控制器通信,因为访问是通过最后一级缓存进行过滤的(只有少数例外,例如经过它的不可缓存访问,以及具有另一个控制器的IO访问)。除了它们自己的专用缓存之外,所有核心都将共享该缓存存储

现在有一个关于共享的注意事项-如果2个(或更多)内核同时需要相同的数据,你很幸运-要么它已经在缓存中(在这种情况下,两个访问将依次通过向每个内核发送数据副本并将其标记为“共享”),要么如果数据不存在,两个都将等待MC带来它(一次),然后继续处理hit案例。
但是,如果一个或多个内核需要将新数据写入该行或其中的一部分,则有一个例外。在这种情况下,修饰符将发出读取所有权请求(RFO),这将阻止共享该行并使其他内核中的所有副本无效,否则您将面临失去缓存一致性或一致性的风险(因为一个内核可能使用过时的数据或感知不正确的内存顺序)。这在并行算法中被称为竞争条件,也是复杂锁定/防护机制的原因。再次-请注意,这与实际RAM访问是正交的,可能同样适用于最后一级缓存访问。

您可能还想了解。多核和多CPU之间也存在差异(从内存管理的角度来看),因为同一物理CPU上的多核将共享(至少部分)缓存内存。所有的内核都可以从RAM中读取,尽管它不能“字面上”同时进行。它们是典型的具有多核的现代CPU,将在所有核之间实现共享的上层缓存。为什么要发明轮子?:)为什么不采取类似OpenBLAS的方法,看看它的实现呢?因为我认为OpenBLAS太复杂了。当我查看存储库()时,我不知道从哪里开始。我认为这通常用于计算机矩阵乘法: