CPU性能发展所遇到的瓶颈

通常一个处理器通常包含多个核心(Core),集成 Cache 子系统,内存子系统通过内部或外部总线与其通信。在经典CPU中一般有两个常用的组件:北桥(North Bridge)和南桥(SouthBridge)。它们是处理器和内存以及其他外设沟通的渠道。图1给出了处理器、内存、南北桥以及其他总线之间的关系。

 

从图一可以看到:

1)处理器访问内存需要通过北桥。

2)处理器访问所有的外设都需要通过北桥。

3)挂在南桥的所有设备访问内存也需要通过北桥。

那么CPU访问南桥上的外部设备和北桥上的DDR内存的访问速率受CPU的主频、Local Bus带宽、南桥外设总线的速率、CPU取指令机制等多方面所影响。

处理器主频和集成度在过去二十年里一直按照摩尔定律在发展,从单核到多核以及超线程。处理器的性能提高不少,同时处理器的功耗也正比于主频的三次方在增加。因为使用的晶体管栅极材料存在漏电现象,高频率下电子迁移显著,势必为导致产热量增加,散热带了重大问题。CPU欢快的朝着频率越来越高的方向发展,受到物理极限的挑战,又转为核数越来越多的方向发展。由于所有CPU Core都是通过共享一个北桥来读取内存,随着核数如何的发展,北桥在响应时间上的性能瓶颈越来越明显当北桥出现拥塞时,所有的设备和处理器都要瘫痪。这种系统设计的另外一个瓶颈体现在对内存的访问上。不管是处理器或者显卡,还是南桥的硬盘、网卡或者光驱,都需要频繁访问内存,当这些设备都争相访问内存时,增大了对北桥带宽的竞争,而且北桥到内存之间也只有一条总线。

为了改善对内存的访问瓶颈,出现了另外一种系统设计,内存控制器并没有被集成在北桥中,而是被单独隔离出来以协调北桥与某个相应的内存之间的交互。系统结构如图2所示。

图 2 所示的这种架构增加了内存的访问带宽,缓解了不同设备对同一内存访问的拥塞问题,但是却没有改进单一北桥芯片的瓶颈的问题。

 

 

为了解决北桥北桥在响应时间上的性能瓶颈,把内存控制器(原本北桥中读取内存的部分)也做个拆分,平分到了每个CPU上。于是NUMA(Non-Uniform Memory Access)就出现了。内存控制器集成到CPU内部,Intel第二代酷睿I系列以及将主板北桥合并到CPU内部,所以Intel第二代酷睿I系列没有北桥,只有南桥。AMD没有吞并北桥。顺便补充一下Intel 单个socket只支持单个node,AMD 单个socket配对个node。(Node,socket,core,thread)是NUMA中的概念,linux下查看cpu参数通过如下命令:

  1. lscpu

                                                                                            图3

图3可以看出CPU是小端模式,每个CPU有一个core,每一个core有一个thread。三级cache大小,Flags查看支持的大页内存,比如pse 代表支持2MB的内存页,pdpe1gb代表支持1G内存页。

  1. cat /proc/cpuinfo

从图4可以到Core  ID、超线程数、Core的16进制编码(在DPDK应用中会用到这些参数)。

NUMA设计框架如图5所示。红色绿色箭头代表访问处理器本地内存(Local memory),红色箭头访问远程内存(remote memory),即其他处理器的本地内存,需要通过额外的总线!

NUMA中,虽然内存直接attach在CPU上,但是由于内存被平均分配在了各个die上。只有当CPU访问自身直接attach内存对应的物理地址时,才会有较短的响应时间(后称Local Access)。而如果需要访问其他CPU attach的内存的数据时,就需要通过inter-connect通道访问,响应时间就相比之前变慢了(后称Remote Access)。所以NUMA(Non-Uniform Memory Access)就此得名。

从前面分析发现,确实提高了CPU访问内存和外设的速率,奈何CPU处理速率远远超过了内存的吞吐速率,这里就带来了CPU不必要的开销。一般来说,当CPU从DDR中取指令时,大概要花费几百个时钟周期,在这几百个时钟周期内,处理器除了等待什么也不能做。在这种环境下,才提出了Cache的概念,其目的就是为了匹配处理器和内存之间存在的巨大的速度鸿沟。

Cache 由三级组成,之所以对Cach 进行分级,也是从成本和生产工艺的角度考虑的。一级(L1)最快,但是容量最小,一级cache分为指令cache和数据cache,图3中可以查看;三级(LLC, Last Level Cache)最慢,但是容量最大。当CPU需要访问某个地址时候,首先在cache中目录表中查询是否有该内容,有就直接取指令或者数据,没有就从DDR中取取指令或者数据。在cache有对应的数据简称指令命中,反之指令没有命中。L3 cache命中,大约需要40个时钟周期,L3 cache没命中,一个内存读需要140个时钟周期。

Cache 的预取指令分为时间局部性和空间局部性。时间局部性是指程序即将用到的指令/数据可能就是目前正在使用的指令数据。因此,当前用到的指令/数据在使用完毕之后以暂时存放在Cache中,可以在将来的时候再被处理器用到。空间局部性是指程序即将用到的指/数据可能与目前正在使用的指令/数据在空间上相邻或者相近。因此,在处理器处理当前指令/数据时,可以从内存中把相邻区域的指令/数据读取到Cache中,当处理器需要处理相邻内存区域的指令/数据时,可以直接从Cache中读取,节省访问内存的时间。这里可以创建一个二维数组,然后顺序横向a[i][j]和竖向a[j][i]赋值计算时间做对比,由于a[j][i]地址是跳跃性的赋值,cache不能命中,所以消耗的时间远远大于连续地址的赋值。

提高CPU性能还可以采用多核并行计算,一个时钟周期读取N条指令。在软件上也可以做适当的系统优化和算法优化,比如配置CPU 亲和性,CPU 亲和性(Core affinity)就是一个特定的任务要在某个定的 CPU 上尽量长时间地运行而不被迁移到其他处理器上的倾向性。

 

本文出自Linux_Google原创,转载请注明转载出。

欢迎关注新公众号:herok,分享计算机办卡,嵌入式,AI等高质量技术干货文章。

公众号二维码:

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页