了解到在同一CPU的不同内核上执行多个线程的可能性。那么线程上下文切换的定义是否仍然保持不变? 我的意思是地址空间是否仍将在不同内核中的线程之间共享。此外,同步块是否仍然对在不同内核中运行的线程保持安全?
是的,所有现代 CPU 都实现了对称多处理 (SMP) 系统。也就是说,所有内存都出现在所有CPU上所有内核的地址空间中,所有内核上的相同地址是指内存芯片中的相同字节。
在硬件方面,这远非理想。现代 CPU 不是真正的 SMP,而是在非统一内存架构 (NUMA) 之上合成的 SMP;不同的存储器位于不同CPU(或在某些架构上,不同内核)的不同地址总线上。因此,一个 CPU 上的内核不能直接寻址另一个 CPU 上的内存。
英特尔,AMD等所做的是在CPU/内核之间实现了非常快速的网络通信通道。因此,当内核尝试访问未直接连接到它的内存地址时,它会通过通道向连接到正确内存芯片的内核发送请求。该核心执行查找,通过网络将内容发送回去。像这样的流量很多,使缓存保持最新,等等。
这并不理想,因为有相当多的硅专门用于运行这个网络,否则晶体管可能会用于实现更多的内核。
我们这样做只是因为,在过去,让多个CPU工作的廉价方法是将2个芯片粘在相同的内存地址/数据总线上。 便宜,因为硬件便宜,多线程软件(习惯于在单个CPU内进行上下文切换)并没有真正注意到差异。
首先,这还不错 - 与CPU相比,内存并没有那么慢。然而,它很快就变得不可持续,但到那时,世界上有太多的软件期待SMP环境(像所有主要操作系统一样的小东西)。因此,虽然当时理想的硬件架构转变是纯粹的 NUMA(该死的软件),但商业现实是 SMP 必须坚持下去。因此出现了英特尔的QPI,AMD的Hypertransport等互连。
具有讽刺意味的是,相当多的现代语言(Golang,Rust等)支持消息传递(CSP,Actor模型)作为语言的一部分。这正是如果底层硬件是纯 NUMA 时将被迫采用的编程范式。所以我们有了它;适用于 NUMA 机器的消息传递范式,由 SMP 架构之上的时尚语言实现,而 SMP 架构又在实际的 NUMA 硬件之上合成。如果你认为这很疯狂,你并不孤单。
您可以将 QPI、HyperTransport 等视为有点像以太网附加内存,CPU 或内核充当其他 CPU 和内核的内存服务器。只有QPI,Hypertransport要快得多,而且这一切都隐藏在CPU上运行的软件之外。