从核心性能不一致到sub-numa

既然都是9102年了,云计算早就成了服务器的主要任务,就如同我之前说过的:“那种期待一个应用就把一台主机塞满的时代是回不来了!”不同于服务传统的称之为“科学计算”的模式,云计算的业务场景要求CPU的隔离性更优于性能,尽可能的各个core之间是搭积木似的即可随意打通(单虚机多CPU)又要互不干扰的。Xeon为代表的服务器CPU给出的主流解决方式是单socket,更多核心。

PS:如果对NUMA概念比较模糊的话,建议阅读本站几篇NUMA的帖子:

Linux的NUMA机制
深挖NUMA
UMA-NUMA之性能差异

更多的核心带来更大面积的CPU芯片,而更远的传输距离势必将会带一个工程上的问题:核心之间的通讯 (C2C)以及内存访问(C2M)的时延问题。且不说在CPU时钟周期以纳秒为单位的时代,接近光速的信号电流传输速度事实上已经成为了一面看得见摸得着且随时可以撞上的墙(c=30cm/ns)。更要命的是,同样是远近的不一致性,导致了同一块CPU上局部核心之间存在由于时延不同带来的性能差异,即位置决定性能。

  • C2C:各个CPU core之间需要通过L3同步数据以及保持L2缓存以下的一致性问题。
  • C2M:core没有自己的内存控制器,所有的core共享的是socket上少数几个内存控制器。

如何设计c2c,c2m的通讯结构成为了一个阻碍CPU核心数增加的难题。

最初,Xeon最早给出的设计是一个双线环网结构,有点类似于上海地铁4号线。每个CPU core是一个ring stop,此外内存控制器,QPI,PCIe控制器各有一站。 没错!顾名思义这里的stop真的就是地铁站的stop概念。“乘5站”的核心自然比“乘1站”的性能差。

E5_v4_LCC.png (533×758)

环网系统最大的缺点就是,随着核心数量的增加,“最后一站”带来的时延会越发明显,不具备无限扩张的能力,于是在更多核心的版本上出现了两个环网的设计。每个环网有自己的内存控制器,同时为保持整个系统的一致性,两个环网之间又增加了两个“换乘站”用于环网之间的数据交换。

那么,问题来了,内存要求强一致性,两个内存控制器访问的内存地址是相互独立的,本地的core需要访问远程内存的话必须要经过“换乘站”,而换乘站为控制流量很可能要动用队列,时延会有显著的放大,时延跟CPU的核心性能直接挂钩。这跟NUMA面临的问题是一致的。这个时候解决这种不一致的方式被称为cluster-on-die(COD),但是sub-numa也就是在同一个核心上细分两个NUMA节点的设计呼之欲出。

题外话:如果核心数介于“一个环太多,两个环太少”时会有怎样的设计,那你听说过上海地铁3号线和4号线的关系吗?够随意了吧!这也就是为什么没有在v4这一代推出sub-numa的原因之一吧。

双环的结构实际上已经走到了尽头,从结构上推算就能看的出所谓3环及以上的设计是不可能实现的。对更多核心数的要求不会停止,于是在Skylake这一代(V5)终于推翻了环网的结构,取而代之的是更为复杂的mesh。

Mesh结构更像是互联网通讯的模式,数据的发送需要一系列的路由跳转从出发点到目的地。尽管内存控制器MC已经放置在了整块CPU die居中最外侧的位置,但对应的时延还是存在一致性问题,C2M这边离内存控制器较近的core会享受到更低的时延,较远的core就会有较高的时延;c2c也有类似的问题,牵扯另一更为复杂的设计,不提。

于是sub-NUMA的技术被正式推出。每个内存控制器只负责离自己较近的14个core,保证所有的c2m访问都在6跳以内以控制各种访问时延。

之后的问题又来了,所谓的IA架构,I和A两家都不约而同地在之后的服务器CPU中采用“胶水设计”(A: Naples, I: CooPer Lake),即在一个socket上封装两个以上的die,把传统意义上的CPU看成一块扩展电路板。c2c或者说die-to-die的时延就会变得更加明显(且不可理喻)。

下一步怎么玩呢?谁知道呢?

推荐阅读:
首先列出本站之前相关的几篇帖子
事出这一段时间做了不少基于SP
继续在NUMA和性能差异的路上

发表评论

电子邮件地址不会被公开。 必填项已用*标注

请补全下列算式: *

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据