您好!
欢迎来到京东云开发者社区
登录
首页
博文
课程
大赛
工具
用户中心
开源
首页
博文
课程
大赛
工具
开源
更多
用户中心
开发者社区
>
博文
>
现代 CPU 技术发展
分享
打开微信扫码分享
点击前往QQ分享
点击前往微博分享
点击复制链接
现代 CPU 技术发展
29****
2023-12-13
IP归属:北京
195浏览
# `介绍` 这篇文章主要是介绍`CPU`技术的发展,包括最近几十年`CPU`性能提升和半导体工艺发展,当前技术发展方向。希望可以帮助软件开发者理解`CPU`指令集和组成运行原理、`CPU`性能提升的现状和瓶颈、`CPU`技术发展方向会如何影响`软件开发/设计`的框架和编程思想。 > 提示:因为是面向软件开发者,所以会忽略掉一些电路设计、制造工艺等底层的硬件知识。同时也不会特别深入的介绍每个知识点,只是提供一个概览。 #### `CPU 指令集和运行原理` 当前使用最广泛的指令集是`x86`、`ARM`、`RISC-V`,指令集对于`CPU`性能和`软件开发`有多大的影响,指令集的发展方向是什么。现代`CPU`内部微架构、流水线是如何设计的,为什么`CPU`的控制单元和缓存相比`GPU`复杂很多。 #### `CPU 性能提升和未来方向` 近些年`CPU`性能提升遇到了`功耗墙`的问题导致提升速度放缓,为什么以前的优化技术都遇到了瓶颈,同时当前有哪些新的技术方向用于提高`CPU`的性能。 #### `CPU 技术方向对软件开发技术的影响` 软件最终会在`CPU`上运行,更好的利用`CPU`提供的能力进行编程才能带来更好的性能。一部分`CPU`优化技术是内部微架构调整对软件开发者是透明的,例如`时钟频率`和`IPC`的提升。但是另一些优化技术需要软件开发者进行优化,例如`多核心`、`SIMD`、`DSA`等。这些需要软件开发者改造的技术会如何影响编程语言和系统框架的设计,从而影响软件开发者的编程方式。 # `CPU 结构和原理` ## `计算机结构` ![冯诺依曼结构](https://img11.360buyimg.com/img/jfs/t1/182721/38/40075/7118/6541f3c0F2eeb6adb/e7a3345c3af62ec1.png) 1945 年`冯诺依曼`提出了一种计算机实现的结构设计,现代的计算机和`CPU`基本上依然是基于冯诺依曼结构的思想进行实现。冯诺依曼结构定义了计算机的`5`个组成部分,分别是`内存`、`控制单元`、`运算单元`、`输入`、`输出`: | 模块 | 功能 | | :-- | :-- | | 内存 | 内存是一个存储器。操作指令和数据以二进制的形式存储在内存中。 | | 控制单元 | 控制单元是一个协调者。`控制单元`按照程序指令顺序从`内存`中读取指令进行执行,将指令发送到`运算单元`进行计算。同时`控制单元`也会协调`内存`和`输入/输出`设备之间的数据传输。 | | 运算单元 | 计算单元包含加减乘除等计算器。`运算单元`根据`控制单元`发送的指令,从`内存`中读取数据进行计算,计算完成后重新写回到`内存`中。 | | 输入/输出 | 输入/输出设备主要是外部的一些设备进行数据交换。输入设备将数据和指令输入到计算机中,常见的输入设备有`键盘`、`鼠标`。计算机处理后将数据输出到外部设备中,常见的输出设备有`显示器`。 | > 提示:还有一种不同的架构是`哈佛架构`,它是一种程序指令和数据分开的计算机结构。现在`L1缓存`中就是使用哈佛架构的思想将`指令`和`数据`缓存分开存储。 ## `CPU 结构` ![CPU结构](https://img14.360buyimg.com/img/jfs/t1/227428/37/5827/9111/656ebb8bF4cbf587f/91c22f7e4910846c.png) 现代`CPU`虽然使用`冯诺依曼架构`思想进行设计,但是经过几十年技术的发展非常复杂。因为`内存`不属于`CPU`内部结构,现代`CPU`主要分为`4`个组成部分,分别是`高速缓存`、`控制单元`、`运算单元`、`寄存器`。这里先简单介绍一下各个组成部分的功能,后面`流水线实现`的部分会更详细的介绍。 #### 高速缓存 `高速缓存`将内存中更频繁使用的`程序指令`和`数据`保存在`高速缓存`中,避免每次都从内存读取降低数据读写延迟。 - `多级缓存` - 现代`CPU`通常有`2-3`级缓存,离CPU更近的缓存速度更快但是容量更低。 #### 控制单元 控制单元是`CPU`中最复杂的部分,负责调度和协调其他部分进行运行。调度流水线执行、异常处理等。 - `流水线调度` - 分支预测、高速缓存读写、指令读取、指令解码、指令调度执行、乱序执行、指令发射、更新寄存器 - `异常处理` - 处理 CPU 运行时的各种异常 #### 运算单元 运算单元包含大量的运算器执行计算任务,包括逻辑运算、分支、内存读写单元。 - `ALU` - 算数逻辑单元负责整数加减乘除和位运算 - `FPU` - 浮点单元负责浮点数运算 - `Branch` - 分支单元用于分支判断,当 CPU 支持分支预测时还需要更新分支预测缓存和分支预测错误回滚执行 - `SIMD` - 向量单元负责向量运算 - `内存读写` - 内存单元负责内存读写,从缓存中读取数据或将数据写回缓存 #### 寄存器 寄存器用于保持运行时的临时数据和`CPU`自身的一些状态值。 - `通用寄存器` - 用于存储临时数据,局部变量/函数参数/返回值等数据 - `PC` - 程序计数器存储下一条指令的地址 - `IP` - 指令指针用于存储当前执行的指令地址 - `SP` - 堆栈指针用于存储栈的地址 # `指令集架构` `ISA`(指令集架构)是一种处理器基本功能和指令集架构规范。它定义了`CPU`硬件可以执行的所有操作指令,指令的编解码格式、指令类型、寄存器、内存寻址、异常处理、权限级别等内容。`编译器`和`CPU`选择一种指令集规范作为标准进行实现,这样可以保证任意符合`指令集`规范编译的代码都可以相同`指令集`规范的CPU上正常运行。`ISA`主要有`指令集`、`寄存器`、`内存模型`、`异常中断处理`等规范定义。 ###### `指令集架构规范组成` - `指令集` - 支持的操作指令、指令的编解码格式、指令长度 - `寄存器` - 支持的寄存器类型、寄存器数量 - `内存模型` - 支持的内存访问方式、内存寻址方式、内存一致性规则 - `异常/中断处理` - 定义了处理器如何处理异常和终端事件 ## `指令集` 指令集定义了处理器可以执行的所有操作指令和指令的编解码格式。目前常见的指令集主要分为两种类型,`复杂指令集`和`精简指令集`。复杂指令集`CISC`主要是以`x86`为代表,精简指令集`RISC`主要是以`ARM`/`RISC-V`为代表。 ### `x86` `x86`指令集架构最早使用在`Intel`在`1978`年推出`8086`处理器,指令集专利由`Intel`和`AMD`拥有。目前主要是在`PC`/`笔记本`和`服务器`市场使用,`x86`的优势在于`软件生态/兼容性`和`高性能`,劣势在`高能耗`和`开放性`: | 特点 | 说明 | | :-- | :-- | | 软件生态 | 发展时间最久技术最成熟,积累了大量的技术和软件。一直很注重兼容性帮助它占有了更多的市场份额,但是兼容性也限制了技术升级和大量的历史包袱需要兼容增加了复杂性 | | 性能高 | 高性能场景占有大部分的份额 | | 能耗高 | 同样性能下`x86`相比`RISC`指令集需要更多的能耗,限制了在低功耗设备上使用 | | 开放性低 | 专利主要由`Intel`所有,其它厂商授权使用 | | 芯片厂商 | Intel、AMD | | 主要领域 | 80%+ PC/笔记本、90%服务器市场 | #### x86 指令集发展 `x86`包含多个扩展指令集,指令长度至少`8`位可变长度。以下是`x86`指令集的一些重要版本更新: | 特性 | 年份 | 说明 | | :-- | :-: | --- | | 16 位 | 1978 | Intel 在 1978 年推出`16位`指令集使用在`8086`处理器 | | 32 位 | 1985 | Intel 公司推出了 x86 指令集的`32位`扩展,可支持 32 位软件运行 | | 64 位 | 2003 | AMD 公司推出了 x86 指令集的`64位`扩展,可支持 64 位软件运行 | | SSE | 1999 | Intel 推出了 第一代 SIMD 指令集扩展 `SSE`,可支持固定 128 位数据的向量计算 | | AVX | 2011 | Intel 推出了 第二代 SIMD 指令集扩展 `AVX`,可以支持 256-512 位数据的向量计算 | | x86s | 2023 | Intel 推出的纯 64 位架构的白皮书,希望可以减少对于 16、32 位的支持降低兼容性包袱 | ### `ARM` `ARM`指令集架构是英国 ARM 公司开发的一种`RISC`指令集架构,指令集专利由`ARM`公司拥有。`ARM`诞生于`1980`年代,当时的处理器都是基于`CISC`设计复杂度高、功耗大,`ARM`公司希望使用精简的指令集实现低功耗和高性能,可以应用在嵌入式设备和移动设备中。 因为`ARM`有非常好的`能效`优势,目前主要是使用在追求功耗比的`嵌入式`和`移动设备`。`ARM`设备几乎占据所有的`手机`和`Pad`市场。在`笔记本`市场因为苹果切换到`ARM`,同时`高通`和`INVIDIA`开始布局`ARM`桌面端芯片未来也会推动`ARM`份额的提升,目前已经占据了`15%+`的笔记本市场份额。近年`ARM`性能和芯片设计水平逐渐提高,`ARM`在`服务器`市场的份额逐渐提升。 不过`ARM`也有和`x86`同样的问题就是开放性,导致`ARM`受到了`RISC-V`的挑战。`ARM`指令集专利属于`ARM`公司,同时`ARM`公司对使用指令集会有一些限制。 | 特点 | 说明 | | :--: | --- | | 软件生态 | 手机/Pad移动设备和 Mac 系统比较完善,但是`Windows`平台还是会有兼容性问题使用率很低 | | 性能高 | 峰值性能相比`x86`竞品性能略低,不过近年也在高速发展 | | 能耗低 | 因为ARM追求低功耗比的设计,同时大量低功耗设备厂商的硬/软件优化,能耗比一直领先 | | 开放性中 | 专利由`ARM`所有。虽然比`x86`开放性会好一些,但也导致部分厂商开始尝试完全开源的`RISC-V`。同时由于`RISC-V`的竞争,`ARM`也适当放宽了对于自定义指令集的限制 | | 芯片厂商 | Apple、高通、华为、联发科 | | 主要领域 | 几乎所有移动设备、14%笔记本市场、7%服务器市场、嵌入式 | #### ARM 指令集发展 ![ARM](https://img11.360buyimg.com/img/jfs/t1/186477/12/37004/57560/653f5d37F89733f2a/b970d21cdc1a26e9.jpg) `ARM`包含多个扩展指令集,指令长度为固定`32`位。以下是`ARM`的一些重要版本更新: | 指令集 | 版本 | 说明 | | :-- | :-- | --- | | 32 位 | Armv1 | 1985 年 ARM 推出了`32位`架构的指令集 | | NEON | Armv7 | 2004 年 ARM 推出了第一代 SIMD 指令集扩展`NEON`,可支持固定 128 位数据的向量计算 | | 硬件虚拟化 | Armv7 | 可支持在同一台物理机上运行多个虚拟机的`硬件虚拟化`扩展 | | 64 位 | Armv8 | 2011 年推出了`64位`扩展,可支持 64 位软件运行,有`31`个 64 位通用寄存器 | | SSE | Armv8.2 | 2014 年 ARM 推出了第二代 SIMD 指令集扩展`SSE`,可支持可变长度 128-2048 位数据的向量计算 | ### `RISC-V` `RISC-V`架构是`2010`年由加州大学伯克利分校发起的开源`RISC`指令集架构标准。`RISC-V`有以下几个优势: - `精简设计` - 设计非常简单,相比`x86`和`ARM`指令集设计更加精简,降低了复杂度和指令数量。 - `模块化设计` - 采用模块化设计思想。提供精简的基础指令集实现基础能力,其它包括`浮点`、`SIMD`、`原子操作`、`位运算`等指令都是通过扩展指令集提供。芯片设计厂商可以基于自身需求将各种指令集扩展模块进行组合应用到不同的场景。 - `开源` - `x86`/`ARM`都需要授权才能使用,`RISC-V`完全开源可以免费使用不用担心版权和专利费的问题。 `RISC-V`的优势在于`更先进`的设计和`开源`,劣势在`软件生态`和芯片厂商的`设计能力`还需要进步: | 特点 | 说明 | | :-- | --- | | 软件生态 | 比较弱。目前更多是用在一些嵌入式设备或协处理器中,操作系统、软件开发、用户级软件还在起步阶段 | | 性能中 | 峰值性能相比`x86`/`ARM`性能差一些,更多是因为`x86`/`ARM`芯片厂商的技术更成熟 | | 能耗中 | 和`ARM`差不多,更多是因为`ARM`芯片厂商的技术更成熟 | | 开放性高 | 由于开源吸引了大量芯片设计厂商的加入,支持添加自定义指令集,不过也导致了一些生态兼容性问题 | | 芯片厂商 | 主要是新型芯片设计商,所以设计能力上相比差一些 | | 主要领域 | 1%处理器市场、嵌入式、协处理器(手机上目前已经有不少使用`RISC-V`指令集设计的协处理器) | #### RISC-V 指令集 `RISC-V`有3个`基础指令集`和多个扩展指令集,指令长度为固定`32`位。以下是`RISI-V`常见的指令集: | 指令集 | 类型 | 说明 | | :-- | :-- | --- | | RV32I | 基础指令集 | `32位`整数指令集,包含 32 个 32 位的通用寄存器 | | RV32E | 基础指令集 | 低功耗嵌入式`32位`整数指令集,包含 16 个 32 位的通用寄存器 | | RV64I | 基础指令集 | `64位`整数指令集,包含 32 个 64 位的通用寄存器 | | F/D/Q | 浮点扩展指令集 | 单精度 32 位、双精度 64 位、四倍精度 128 位 | | M | 整数扩展指令集 | 整数乘法除法指令集 | | A | 原子操作扩展指令集 | 原子操作指令集 | | B | 位操作扩展指令集 | 位操作指令集 | | P | SIMD 扩展指令集 | 固定长度的SIMD 运算 | | V | 向量运算扩展指令集 | 可变长度的向量运算 | | C | 压缩指令扩展指令集 | 可将指令长度压缩位 16 位用于低功耗场景 | #### RISC-V 寄存器 ![寄存器](https://img20.360buyimg.com/img/jfs/t1/180877/10/36363/35782/656ec538Ffd413117/cb68459a9d103e30.jpg) #### RISC-V 汇编语言 ![](https://img10.360buyimg.com/img/jfs/t1/109181/16/38020/291241/6566f82cF26485425/a53e39e95bd93423.png) ![](https://img11.360buyimg.com/img/jfs/t1/236644/32/4961/90973/6566f828F0af20668/acb3e9456668f669.png) ![](https://img12.360buyimg.com/img/jfs/t1/90951/32/42175/280741/6566f82cF11078f5a/504a0b4ffab5141f.png) ## `指令编码格式` 指令集规范定义了指令的二进制格式。以`ARM`指令集为例,编译器在编译时按照指令集规范将每一个汇编指令`编码`成`32`位的二进制指令,`CPU`在运行时通过解码器按照指令集规范将二进制指令`解码`成特定的指令进行执行。 `x86`指令集更复杂,`ARM`和`RISC-V`更精简。`x86`使用可变长度指令,至少`8`位+,同时`x86`支持更多的内存寻址模式。`ARM`使用固定`32`位指令,至少少数几种内存寻址模式。 ###### ARM指令编码格式 ![指令集格式](https://img13.360buyimg.com/img/jfs/t1/232857/19/6018/53148/65700c33F5da8aed7/3bd11858664b6417.png) ## `指令集对比` ### `复杂指令集和精简指令集` `x86`是复杂指令集,主要是因为`x86`指令数量多、复杂指令、内存寻址方式多、指令长度不同等原因,导致硬件设计实现更复杂。使用复杂指令集主要是行业早期`技术限制`和`兼容性`原因导致的: | 原因 | 说明 | | :-- | --- | | 编译器技术落后 | 程序大多数都是以`汇编语言`或`二进制码`进行编写。提供一条复杂高级指令执行多个指令操作,可以使程序开发更加便利。 | | 内存紧张 | 程序需要加载到内存中执行,内存不足导致需要尽可能降低程序的二进制大小减少内存占用。复杂指令是可变长度,大部分指令的二进制位数更短,只有复杂指令会使用更长的二进制位数,这样可以增加指令的存储密度降低大小。 | | 通用寄存器少 | 由于晶体管的成本导致通用寄存器数量很少,指令会更多的直接访问内存。导致更多的指令支持内存寻址,内存寻址方式更复杂。 | | 兼容性 | 不断增加新的指令,同时还需要完全兼容老的指令,导致指令数量越来越多。 | 以上这些原因导致早期使用`CSIC`将更多的复杂性转移到`CPU`处理,导致`CPU`设计复杂成本高。之后随着半导体技术的发展可以集成更多`晶体管`和`内存`以及`编译器`技术的发展可以更好的生成机器代码,`1979`年开始行业逐渐发现`CISC`有以下这些缺点: | 原因 | 说明 | | :-- | --- | | 通用寄存器数量少 | 更多的使用寄存器可以减少对内存的访问同时指令执行平均周期差异小也有利于流水线执行。 | | 实现复杂度高 | 指令数量多/复杂指令,导致处理器实现复杂成本更高。同时也会增加编译器的复杂度 | | 不利于流水线的设计 | 处理器流水线技术可以使处理器同一个周期内并行执行多个指令和操作流程,例如指令解码/内存读写/计算。指令长度不同和复杂指令会使解码器更复杂,指令执行周期差异大也不利于流水线并行执行 | | 指令使用率低 | 程序的常用指令只占整个指令集的`20%`,造成了很多浪费 | | 能效高 | 由于复杂度高需要使用更多的晶体管和复杂度,导致产生更多的功耗无法应付低功耗场景 | 以上这些缺点推动了新的指令集都使用`RISC`设计更有利于提高处理器的性能和能效。但是`Intel`因为兼容性和软件生态的考虑选择继续使用`x86`。经过这些年处理器技术的发展,`x86`也做了非常多的技术改进提高性能,不过由于兼容性约束指令集很难缓慢的进行改进。 `x86`的一些技术改进: - `降低指令复杂度` - 持续减少对一些老旧指令的兼容减少指令数量 - `内部使用精简指令集的设计` - 由于半导体工艺的发展芯片可以集成更多晶体管提高性能。增加了通用寄存器的数量、内部将复杂指令解码为多条简单指令用于流水线执行。 - `更多技术支持` - 提供了很多基于`Intel`平台的指令集扩展和开发框架,操作系统和软件开发者可以利用这些技术提高性能。 ###### 指令差异 以下面的汇编为例。`RISC`指令集必须将内存数据加载到寄存器以后才能计算,`CISC`指令集可以支持指令内存寻址。所以`RISC`会生成更多的指令数量。 - CISC ``` mov eax, [num1] ; 将num1的值加载到寄存器EAX中 add eax, [num2] ; 在寄存器EAX中执行加法操作 mov [result], eax ; 将结果存储到内存地址result处 ``` - RISC ``` lw num1, [num1] ; 将num1的值加载到寄存器R0中 lw num2, [num2] ; 将num2的值加载到寄存器R1中 add r0, r1 ; 在寄存器R0中执行加法操作 sw r0, [result] ; 将结果存储到内存地址result处 ``` #### 指令集架构实现对比 因为`ARM`和`RISC-V`都是精简指令集设计上很接近,所以使用`x86-64`和`ARM64`来对比实现上的一些细节。 | 特性 | x86-64 | ARM64 | 影响 | | :-- | :-- | :-- | --- | | 指令位数 | 长度不同,至少8位 | 固定32位 | 可变长度导致解码器和指令读取复杂度更高 | | 指令数量 | 几千个 | 几百个 | ARM 主要是使用频率高的基础指令和少量指令扩展。x86除了基础指令还包含大量的复杂指令,同时为了兼容性需要支持很多老旧不再使用的指令 | | 指令执行时间 | 简单指令大部分相同 | 基本相同 | `ARM`大部分基础指令执行时间都在一个时钟周期。x86因为包含复杂指令执行时间不太一样,复杂指令可能会解码成多条微指令执行 | | 通用寄存器数量 | 16 | 31 | 通用寄存器数量越多,可以将更多的临时数据存放在寄存器中减少对内存的读取提高性能 | | 内存读写方式 | 寄存器、内存模式 | 寄存器操作 | x86 很多指令都可以直接操作内存。ARM 必须使用`LOAD`/`STORE`将内存读取到寄存器或寄存器写入到内存中。不过现代流水线设计`x86`也会解码为多条微指令类似`ARM`的处理器方式 | | 编译器复杂度 | 中 | 高 | x86复杂度高导致编译器实现更复杂 | | CPU复杂度 | 高 | 中 | x86指令数量更多/长度不同/复杂指令会导致CPU复杂度更高 | | 程序二进制大小 | 中 | 高 | 对于x86的一条复杂指令,ARM可能会生成多条简单指令。所以 ARM 密度更低,指令二进制会更大导致程序更大一些 | ## `其他` ### `CPU 遇到不支持的指令如何处理` 指令集通常包含`基础指令集`和`扩展指令集`,基础指令集是使用最频繁的指令,扩展指令集是用于一些特定场景的指令集,例如`64位`和`SIMD`支持。通常`CPU核心`只会支持一部分扩展指令集,因为支持更多指令可能会增加额外的计算单元和寄存器,这会导致耗费更多的晶体管增加`成本`和`功耗`。同时一些使用频率低/成本高的扩展指令只用在部分追求高性能的场景。以下是两种情况: - `不支持部分扩展指令集`:`Intel`酷睿12系列开始不再支持`AVX-512`向量扩展,只有在更高级的`至强`处理器才支持。`AVX-512`需要多个`512`位寄存器,多个支持`512`位向量运算的计算单元。移除`AVX-512`指令扩展可以节省晶体管数量降低功耗或者将这些晶体管用于其他能力。 - `大小核差异化处理`:`高通`骁龙8gen2处理器,大核只支持`64`位,小核支持`32/64`位。`CPU`继续支持32位应用运行,32位应用可以继续在小核上运行。但是同时支持32/64位也会增加`CPU`的复杂度增加成本和功耗,所以在`8gen3`处理器中已经完全移除了对32位的支持。 当`CPU`遇到不支持的指令如何处理,通常`CPU`会采用几种处理方式: - `抛出异常` - 直接抛出异常停止执行。 - `模拟执行` - 解码成更简单的指令进行模拟执行,但是可能会导致性能降低。 ### `x86 和 ARM 的性能` 当前总体来看能耗比`ARM`更优秀,高性能场景`x86`使用率更高。但是`指令集`对于`CPU`性能和功耗的影响会越来越小,`制造工艺`、`使用场景`、`兼容性`等因素也会导致`x86`和`ARM`平台的性能差异。 | 特性 | x86-64 | ARM64 | 影响 | | :-- | :-- | :-- | --- | | 制造工艺 | 最新 7nm | 最新 3nm | `Intel`半导体工艺制程一直落后于`台积电`,ARM 芯片大多使用`台积电`最新工艺制造 | | 使用场景 | PC、服务器 | 移动设备、笔记本、嵌入式 | `x86`面向高性能设计有更强大的散热能力,追求更高的峰值性能对于能耗的关注不够。`ARM`设备更多是面向低功耗的移动设备,续航和散热能力都有限,包括`CPU`、`操作系统`、`设备`都会使用面向高能效的设计。例如`ARM`会使用`SOC`、`大小核`、`统一内存`等有利于高能效的设计,操作系统基于高能效对`CPU`进行调度。 | | 兼容性 | 兼容性负担重 | 兼容性负担轻 | `ARM`平台最新的处理器已经不再`32`位,`x86`依然需要支持`32`位、部分`16`位模式、大量陈旧指令和模式 | 随着`ARM`逐渐开始在高性能电脑和处理器市场占据更多的份额,也在不断的提升`CPU`性能。`x86`逐渐减少兼容性包袱同时也更加关注`能效比`。可能未来我们可以更清晰的理解指令集架构导致的性能和能耗差异。 ## `小结` 现代指令集架构也在互相借鉴,指令集之间的差异越来越小。`x86`CPU 内部会将复杂指令解码成多个简单指令执行有利于超标量 CPU 指令级并行,`ARM`也添加更多的指令以支持更多场景,`RISC-V`的设计者认为`ARMv8`借鉴了很多`RISC-V`的设计。 二进制翻译技术的使用也越来越多。`MacOS`提供`Rosetta 2`软件支持`x86`程序在`ARM`芯片上运行,虽然将`x86`指令转换成`ARM`指令会导致一定的性能损耗和兼容性问题(部分指令不支持),但是可以帮助大部分`x86`程序在`ARM`平台上正常运行。同时`Windows On ARM`也支持`x86`程序在`ARM`芯片上仿真执行。 同时从指令集版本升级特性也能看出,近些年指令集的变更主要是在提高`向量运算`指令应对越来越多的`AI`和`多媒体`场景,其他指令改进很少。 # `处理器技术发展` 处理器技术的发展主要是提高处理器的运行性能。对于如何提高处理器的性能,我们先用一个简单的公式来度量处理器的性能: ``` 程序执行耗时 = 指令数 / CPI / 时钟频率 ``` - `指令数` - 程序执行需要的指令总数 - `CPI` - 处理器平均每个时钟周期可以执行的指令数量(多核心也会增加CPI) - `时钟频率` - 处理器一秒钟可以执行的周期次数 因为指令数量无法控制,所以只能通过提高`CPI`和`时钟频率`来提升处理器的性能。接下来我们来了解处理器通过哪些技术来提高`CPI`和`时钟频率`。 # `半导体工艺、时钟频率、能耗、晶体管数量` ## `功耗、时钟频率、性能` 当前提升处理器性能遇到的最大的挑战就是`功耗墙`。电流通过晶体管会带来热量,太高的功耗导致处理器温度过高无法运行,同时移动设备电池技术发展也非常缓慢。我们先来看看处理器`动态功耗`计算公式,即处理器晶体管开关切换过程中产生的能耗: ``` 功耗 = 晶体管数量 * 电容 * 电压^2 * 时钟频率 ``` > 提示:这里只是一种简单的功耗工时,还需要考虑半导体制造工艺和漏电造成的影响。 从功耗公式可以看出功耗和`晶体管数量`、`电容`、`电压`、`时钟频率`成正比,增加晶体管数量和提高频率都会增加处理器的功耗。 早期半导体工艺发展通过不断降低晶体管的尺寸可以减少`电容`的大小、以及降低晶体管开关切换时间,芯片可以使用更低的`电压`运行,通常每次工艺提升可以使电压降低`15%`。处理器制造商可以不断在芯片上增加`晶体管数量`以及提高`时钟频率`,同时控制功耗的增长速度。 ###### 半导体工艺发展带来的提升 - `增加晶体管数量` - 在同样尺寸的芯片中集成更多数量的晶体管,这些增加的晶体管可以用于增加缓存大小、控制单元等模块提高处理器的性能。同时也推动了 SOC 芯片的发展,在芯片内集成多核心、GPU 等单元。 - `提高时钟频率` - 提高时钟频率可以使处理器执行的更快 - `降低电压` - 使用更低的电压进行运行,在同样的性能下可以降低能耗。同时更好的晶体管设计可以降低漏电。 ###### 技术定律 > `登纳德缩放定律`:1974年罗伯特·登纳德发现,由于晶体管尺寸变小,在固定的芯片面积上增加晶体管的数量不会增加功耗。 > `摩尔定律`:1965年戈登·摩尔预测,由于晶体管尺寸逐渐变小,同样面积的芯片上晶体管数量每隔一年翻一番,1975 年改为每隔两年翻一番。 ## `功耗墙` 从`2004`年开始`登纳德缩放定律`失效。缩短晶体管栅长本来能降低电压、提高晶体管开关频率,但在栅长缩短到`65nm`左右时,晶体管开关频率增加导致芯片功耗和温度急剧上升。同时,栅长缩短导致`漏电`流急剧增加,这些电能也会转化为热量。目前大概`40%`的功耗是由于漏电导致的,即使晶体管处于关闭状态也会增加漏电能耗。早期每一代新工艺至少可以让晶体管栅长缩小`30%`,虽然现在半导体制造商继续使用现有工艺节点乘以`0.7`作为下一代的节点名称,例如 10nm、7nm、5nm、3nm,然而栅长缩小尺寸已远远达不到这个要求,需要`二十年`左右才能使晶体管数量翻一番。同时每一代新技术节点的制造成本越来越高,每代制造成本相比前一代高几倍。 ## `小结` 由于`功耗墙`的限制,相同电压和电容条件下增加晶体管数量提高核心数量相比增加时钟频率带来的功耗影响更小。同时晶体管尺寸减少速度变缓,增加晶体管数量可能需要增加芯片的面积,但是增加芯片的面积会导致生产良率更低成本更高。处理器设计不再追求单核时钟周期快速提升,朝着`多核心`方向发展通过增加核心数提高指令吞吐量并行执行提高性能。 > 提示:以功耗公式来计算,`1GHz`=10亿。Intel 2006 年推出的`Core 2 E6700`处理器时钟频率`2.66 GHz`、`2`个核心`、2.9亿`个晶体管。所以增加1个核心带来的功耗提高比增加时钟频率`1GHz`低。 ###### CPU能效曲线 ![CPU能效曲线](https://img30.360buyimg.com/img/jfs/t1/221216/6/35266/110705/65700c79F6c518d71/e26d343005d8158e.png) - 更高的性能需要更高的`时钟频率`和`电压`运行,导致能效急剧提升 ###### 时钟频率发展 ![时钟频率提升](https://img13.360buyimg.com/img/jfs/t1/90139/9/46433/69391/65560d60Fd58fd063/1f525d3942137f1c.jpg) - 处理器时钟频率提升幅度逐渐放缓 ###### 半导体工艺发展 ![半导体工艺](https://img11.360buyimg.com/img/jfs/t1/238356/5/5793/37834/65700cc3F572b55e8/239285659fec1f13.webp) 半导体工艺发展主要是依赖光刻技术进步以及更优秀的晶体管设计,下面简单列一下`最近10年`半导体工艺发展的重要节点: - `32nm` - `2010`年`Intel`量产了首批`32nm`处理器第二代酷睿处理器,使用了`林本坚`发明的沉浸式光刻技术。 - `22nm` - `2011`年`Intel`首先在 22 纳米工艺节点上使用了`胡正明`发明的`FinFET`(鳍式场效晶体管)晶体管。`FinFET`减少`50%+`漏电并提高了性能。目前使用在`22nm`节点以下的半导体芯片中。 - `5nm` - `2020`年`台积电`使用`ASML`的新一代`EUV`光刻机,为苹果生产了第一个`5nm`处理器`A14`。相比`7nm`工艺密度提高`80%`、速度提高`15`、能耗降低`30%`。 - `3nm` - `2022`年`台积电`开始量产`3nm`芯片。 - `2nm` - `2025`年`台积电`计划开始量产`2nm`芯片,使用`GAAFET`(围栅场效晶体管)代替`FinFET`晶体管。`GAAFET`可以降低漏电、降低尺寸和提高性能。 ###### FinFET、GAAFET ![](https://img14.360buyimg.com/img/jfs/t1/235465/4/5818/89888/656d5996F5b09fd44/ce3ae86d999bda76.png) ###### 晶体管栅长发展 ![晶体管栅长发展](https://img13.360buyimg.com/img/s1000x1000_jfs/t1/96744/35/35140/25247/6555ba1dFb466c8bf/0e1aa5072226536d.jpg) - 虽然晶体管制造技术节点在不断降低,但是栅长缩小速度越来越慢 # `指令级并行:微架构和 IPC 提升` `IPC`提升主要是提高指令的吞吐量,通过优化处理器流水线的微架构,提高一个周期可以执行的指令数量。 ## `流水线介绍` 在理解流水线之前我们先看简单了解一下程序执行的步骤。通常一个程序指令可能会经历五个执行步骤: - `读取指令` - 根据`PC`寄存器的地址,从内存中读取下一条执行指令到`CPU`中。 - `解码指令` - 将二进制指令解码成具体需要执行的指令,复杂指令可能需要解码为多条指令。 - `执行指令` - 调用执行单元进行运算。 - `读写内存数据` - 从内存中读写计算的数据。 - `写寄存器` - 将运算完的数据写会寄存器。 早期的`CPU`设计只能按照程序指令的顺序进行执行,每个指令都需要经过这五个执行步骤。如果每个步骤需要`200ps`的话,一个时钟周期需要`1000ps`并且只能执行`1`个指令。`3`个指令需要`3000ps`。之后就诞生了`流水线`技术,通过在一个时钟周期内执行多条不同指令的不同步骤,提高流水线的吞吐量实现指令集并行。虽然不能降低单个指令的耗时,但是可以降低多条指令的总耗时。 ###### 五级流水线优化执行 ![五级流水线优化](https://img14.360buyimg.com/img/jfs/t1/228079/11/6136/42097/656d779dF0089fbed/fd48fff731d9a938.jpg) - 理想情况下三条指令在每个周期都执行多个不同的步骤,降低了三条执行执行的总耗时 - 一个时钟周期的耗时取决于这个周期内最长耗时的操作 ## `现代流水线设计` 现代`CPU`核心中的流水线设计很复杂,也会导致`CPU`中的控制单元占比很大。现代`CPU`流水线设计主要为了让运算单元每个周期都可以满负载执行,通常有`10`级流水线,加入了更多的功能模块用于增加流水线的吞吐量提高`IPC`。流水线通常分为`前端`和`后端`,前端主要负责`读取指令`和`解码指令`,`后端`主要负责调度`发射指令`和`执行指令`。接下来我们通过下图的流水线示例来了解现代`CPU`中的流水线设计,参考了当前主流的`CPU`性能核心的微架构实现。 ![现代流水线](https://img30.360buyimg.com/img/jfs/t1/227234/12/6038/97761/656d7970Fa8658fc0/d80b15768cbcc4bb.png) > 提示:`Intel`最早在`2004`年推出了`30+`级流水线的`CPU`,但是流水线数量太长会导致微架构设计非常复杂,同时`分支预测`失败惩罚更高。这些原因导致目前`CPU`通常使用`10`级左右的流水线。 ### `读取指令` `读取指令`将内存中的指令读取到`CPU`中的`指令缓冲区中`,相关的优化是为了降低读取指令延迟和读取更多指令到`CPU`中,提高流水线的吞吐量。 #### `多指令读取` 由于从内存中读取程序指令延迟比较长,现代`CPU`会按照`PC`寄存器的地址一次性读取多条后面需要执行的程序指令`CPU`中,减少后续流水线空闲时间。将指令放在`指令缓冲区`中,等待解码器的使用。 #### `分支预测` 由于一次性读取多条程序指令,会遇到一个问题就是当分支判断的时候由于分支还未执行无法知道后续分支执行的方向。通过添加`分支预测`单元提前预测分支可能的执行方向读取后续需要执行的程序指令。 `分支预测`分为`动态分支预测`和`静态分支预测`。高性能`CPU`核心都会使用`动态分支预测`的方式,分支预测成功率可以达到`80%-90%`。`分支预测`错误会导致分支预测惩罚需要回滚错误分支的指令执行,通常会导致`10+`个周期的流水线惩罚。 ###### 静态分支预测和动态分支预测 | 类型 | 实现方式 | 优点 | 缺点 | 详情 | | :-: | :- | :- | :- | --- | | 静态分支预测 | 编译器 | 实现简单、成本低 | 预测准确性比较差 | 在编译器中插入相关分支预测判断 | | 动态分支预测| CPU | 预测成功率高 | 成本高、增加功耗 | 一种简单实现:在每个分支执行完成的时候,将分支结果保存到缓存中进行统计。`分支预测`执行判断时,根据之前这个分支的执行结果选择概率更高的执行方向。| #### `L1 指令缓存` 为了避免每次从内存中读取指令延迟比较长,将读取过的指令存入缓存中。经常使用的指令就可以直接从缓存中读取,但是`L1缓存`由于读取性能的限制容量有限,通常只有几十KB,在`缓存缺失`的时候可能会从内存中读取指令导致流水线卡顿。 #### `TLB 缓存` 由于`CPU`访问内存时,会将程序空间的虚拟地址映射为物理内存地址,这个映射过程有一定的耗时。通过加入`TLB`缓冲区将转换后的映射加入到缓存中,下次读取程序指令地址时就可以直接读取无需再进行地址转换。 ### `解码指令` `解码指令`将`指令缓冲区`中的指令按照顺序微码为多个微操作放入微操作队列中,相关的优化是为了降低解码耗时和同时解码更多的指令。 #### `预解码` 将`指令缓冲区`中几十个字节的指令解析成多个单独的程序指令,后续再发送到解码器提高解码效率。特别是对于`x86`指令由于指令长度不同,预解码阶段会更加复杂。 #### `多解码器` `解码器`将程序指令解码成`CPU`微操作指令。现代`CPU`核心中通常会添加多个解码器用于提高解码性能,通常会有`3-10`个解码器单个时钟周期可以解码多条指令。 `x86`平台的复杂指令可能会生成多条微操作,所以`x86`处理器通常包含一个复杂指令解码器,专门用于解码复杂指令。`x86`处理器的解码器通常比`ARM`更少,`A17 Pro`的高性能核有`9`个解码器,`Intel i9 14900K`的高性能核心只有`6`个解码器其中包含`1`个复杂指令解码器。 #### `微指令缓存` `x86`平台由于复杂指令的存在,解码指令效率更低。通常会加入额外的微指令缓存,将已经解码的指令微操作映射保存到缓存中,下次可以直接读取无需再解码。 ### `发射指令` #### `多发射` 一个周期内发射多个指令到运算单元,提高运算单元的吞吐量。有两种实现多发射的调度方式,`静态调度`和`动态调度`。现代`CPU`高性能核心使用`动态调度`一个周期可以发射`6-10`个指令。 ###### 静态调度和动态调度 | 类型 | 实现方式 | 优点 | 缺点 | 详情 | | :-: | :-- | :-- | :-- | --- | | 静态调度 | 编译器 | 实现成本更低 | 性能提升一般 | 编译器对指令的执行顺序进行调整 | | 动态调度 | CPU | 性能更好 | 成本高、增加功耗 | CPU实时对指令进行调度和发射 | #### `动态调度` 多发射调度主要是为了提高指令发射的效率,同一个`时钟周期`发射出更多的指令到`计算单元`,让`计算单元`持续处于高负载运算状态中提高吞吐量。一个时钟周期内将不同的指令发射到不同的`计算单元`,但是需要解决`流水线冒险`带来的挑战,通常存在三种类型的流水线冒险: - `数据冒险` - 当前指令必须依赖前面一条正在执行的指令的计算结果,例如依赖前一条加法指令的计算结果,需要等待前一个指令将结果写入到寄存器中。 - `控制冒险` - 当前指令必须依赖前面一条正在执行的指令的分支判断结果,通常使用`分支预测`方式进行解决。 - `结构冒险` - 当前指令因为硬件资源限制导致无法执行,例如多个指令需要同时使用同一个寄存器,多个指令需要同时使用某个加法计算单元。 流水线调度过程中需要解决`流水线冒险`的问题,现代`CPU`微架构设计会通过`ROB`(重排序缓冲区)对执行进行动态调度,`ROB`越大可以保存的指令数越多性能越好: - `寄存器重命名` - 现代`CPU`内核中通常有更多的物理寄存器数量,超过`指令集`中定义的寄存器数量。需要对`寄存器`进行重命名放置到不同的寄存器中提高指令级并行,例如两条指令都使用同一个寄存器可以放置到不同的寄存器中进行处理。 - `指令重排序` - 因为需要同时发射多条指令提高吞吐量,所以需要对指令的执行顺序进行调整导致`乱序执行`。但是会保证最终的执行结果符合原本的预期。 - `数据预读取` - 提前将后面程序指令需要使用的内存数据加载到缓存中,避免`缓存缺失`导致的延时。 - `分支预测惩罚` - 流水线执行过程中会将分支预测相关的指令执行结果暂时保存,等待最终分支预测正确时才会执行完成。如果`分支预测`错误需要回滚这些错误预测的指令。 - `指令发射` - 将对应的指令发射到计算单元 ### `执行指令` #### `多执行` 一个时钟周期可以并行执行不同的计算单元,只要当前计算单元有空闲。 #### `计算单元缓冲区` 将指令和指令数据发射到计算单元的缓冲区中等待执行,当计算单元空闲时即可开始执行。 #### `增加计算单元` 增加更多的`整数运算`、`浮点运算`、`分支判断`和`内存读写`单元数量,一个时钟周期可以执行更多的运算和内存读写操作。现代`CPU`性能核心通常有`10+`个算数单元和多个内存加载单元。 #### `L1/L2 数据缓存` 通过`L1`、`L2`缓存读取内存数据,将常用的数据保存到高速缓存中,提高下一次读取的性能。 ## 主流 CPU 核心的微架构设计 现代`CPU`通常使用`大小核`设计,`性能核`有更复杂的流水线设计性能更好,`能效核`流水线设计更简单性能会差一些。 ### Intel `Intel`最新的桌面级别处理器`Core i9 14900K`使用了`8`个`Raptor Cove`性能核和`16`个`Gracemont`能效核。 ###### Raptor Cove性能核 ![](https://img13.360buyimg.com/img/jfs/t1/234008/27/5276/476065/656dc022Fe964e38e/b193e2e14beb0897.jpg) ###### Gracemont 能效核 ![](https://img14.360buyimg.com/img/jfs/t1/221330/11/35275/495637/656dbeabF787274d4/0745f9fd8ed98042.jpg) ### Apple `Apple`最新的`A17 Pro`处理器使用了`2`个性能核和`4`个能效核。 ###### 性能核 ![](https://img12.360buyimg.com/img/jfs/t1/233666/8/5979/621070/656dbfafF0a97b2c9/3f79d1074a8eeaf6.jpg) ###### 能效核 ![](https://img13.360buyimg.com/img/jfs/t1/230657/10/6230/423178/656dbea8F700e445c/f152ee7900c14ea6.jpg) ### ARM `高通`最新的`8 Gen 3`处理器使用了`1`个`X4`超大核,`5`个`A710`性能核,`2`个`A520`能效核。 ###### X4 超大核 ![](https://img12.360buyimg.com/img/jfs/t1/226700/27/5962/619705/656dbf72Fd8739b36/17a3287d644d7abc.jpg) ###### A720 性能核 ![A720](https://img30.360buyimg.com/img/jfs/t1/223108/24/34834/435998/656dbef1F83715cb0/904740a0c6fc8e1b.jpg) ###### A520 能效核 ![A520](https://img30.360buyimg.com/img/jfs/t1/237063/10/5813/288500/656dbf67F41e25b53/ac931e8d249b9bdf.jpg) ## `小结` `CPU`核心微架构通过加入更多的流水线单元提高`IPC`,这些优化单元都需要消耗额外的晶体管数量增加能耗,同时`IPC`更高的核心会使用更高的时钟频率运行。在`20世纪90年代`流水线技术的发展带来了处理器性能的快速提升,但是随着`功耗墙`的限制,高性能核心在性能上比能效核心快几倍,但是在功耗上可能有几十到上百倍的消耗。`CPU`技术发展不再追求大幅提高`IPC`来提高性能,而是转向对晶体管更好的利用追求能耗比。 从现代`CPU`的微架构设计中也能看到,不同指令集的`CPU`在微架构上也有很多相似之处,更多的差异在解码单元对于不同指令的解码。 > 提示:`IPC`高的核心需要使用更高的时钟频率进行执行,主要是因为`IPC`高的核心有更复杂流水线设计和更积极的流水线调度避免流水线停顿,所以提高时钟频率可以提升性能。`IPC`低的核心会遇到更多的流水线停顿,提高频率也会导致很多周期流水线处于停顿等待内存读取或分支计算完成造成浪费。 # `数据级并行:SIMD 和 GPU` ## `SIMD` `SIMD`(Single instruction, multiple data)单指令多数据,是一种通过单个指令同时进行多个数据运算的方式,主要是用于音视频、图像处理、向量运算这些计算场景。通过增加运算单元位宽、计算单元数量数量、寄存器位宽可以同时进行更多数据的运算,普通指令单个周期通常只能支持 2个数据的运算,`SIMD`指令单个周期可以同时几十个数据的运算。同时一次性读取多个内存数据也可以降低多次读取内存数据带来的数据延迟。大部分常见`编程语言`都提供对`SIMD`的支持,可以直接进行使用。 很多图像、音视频等场景,通常只需要更低的数据位宽进行运算,`SIMD`指令可以同时进行更多数据的运算。目前`x86`平台的`SIMD`指令发展到最新的`AVX-512`,运算宽度提升到 512 位,可以单指令执行 512 位的运算。`ARM`平台的`SIMD`指令发展到`SSE`,最高可执行`2048`位的运算。 ``` 例如一个像素值颜色通常使用 RGBA 32 位格式,Red、Green、Blue、Alpha 分别占 8 位。一个 256 位的 SIMD 指令可以同时对 8 个颜色(32 个 8 位)进行运算,普通指令只能进行 2 个 8 位运算。 ``` `SIMD`虽然带来了性能的提升,但是芯片需要使用更多的晶体管用来支持`SIMD`指令更高的位宽计算和更多的寄存器数量。同时`SIMD`指令一次性传输数据量更大、指令复杂度更高、占用更多的寄存器和运算器,也带来了更多的计算功耗。`SIMD`也需要软件开发者针对特定场景选择使用`SIMD`指令进行优化才能得到性能提升。 ###### 普通运算和 SIMD 运算的区别 ![](https://img12.360buyimg.com/img/jfs/t1/125008/12/43102/13348/65700cfbF8ddcd4a6/e2e70576ac03014a.png) ## `GPU` 从某种角度讲,`SIMD`和`GPU`的运算方式很相似。通过一次性并行处理更多的数据带来性能提升,同时一次性读取大量数据也可以降低内存数据延迟带来的影响。`GPU`很像同时并行多线程执行`SIMD`的多核心处理器,只不过相比`CPU`设计更复杂性能更高,同时`GPU`的线程数更多、`SIMD`通道数更多、`SIMD`单元数量更多。 ###### SIMD 和 GPU ![31701598068_.pic.jpg](https://img30.360buyimg.com/img/jfs/t1/231325/7/6041/74903/656d5995Faa2b466b/018358f04491c82f.png) ## `小结` 近些年更多`AI`运算场景增加了对于高性能向量运算的要求。虽然`CPU`通过添加`SIMD`指令增加了向量运算的能力,但是`CPU`本身是用于通用计算设计,`CPU`中只有小部分用于`SIMD`运算。虽然类似`Pytorch`、`TensorFlow`这些`AI`训练框架都支持`SIMD`指令,但是使用`SIMD`进行大规模`AI`训练相比`GPU`性能更低,同时成本更高。`SIMD`更像是传统`CPU`运算的一种补充,用于简单的小规模运算场景用于提高性能。 # `多线程并行:超线程、多核心` ## `超线程` `超线程`是一种`STM`(同时多线程)技术,通过在单个`CPU`核心中模拟运行多个线程提高`CPU`的多线程并行能力。`Intel`最早在`2002`年推出了超线程技术,一个核心同时支持`2`个线程。利用`SMT`可以避免处理器中长延时事件导致的暂停,提高计算单元的利用率。 `超线程`技术通过给每个线程增加一套`寄存器`和`PC`单元,多个线程共享流水线中的`多发射`、`动态调度`等模块,通过寄存器重命名和动态调用可以在一个周期内执行不同线程的多条指令。减少单个线程中发生类似`缓存缺失`这样的长延时等待事件,让计算单元一直在执行状态提高性能和吞吐量。 `超线程`技术会增加流水线调度的复杂度,现代`CPU`核心通常只支持`2`个线程的`SMT`。`超线程`技术需要依赖流水线的动态调度能力,所以现代`CPU`中通常只有高性能核心才支持。同时`超线程`技术虽然可以提高`20%-30%`的多线程性能,但是会增加`7%`的能耗和降低`单核`峰值性能。 ###### 超线程调度 ![超线程](https://img20.360buyimg.com/img/jfs/t1/225772/29/5802/31327/656d5994F38fc651f/363745ecbd0ae5cb.jpg) - `粗粒度多线程` - 只有流水线发生等待事件长的停顿时才切换线程 - `细粒度多线程` - 每个时钟周期都切换线程 ## `多核心` 由于`IPC`提升和`时钟频率`提升都因为`功耗墙`的限制而放缓,现代`CPU`通过提供更多的物理核心提高多线程并行能力提升指令吞吐量提高性能。通过增加`CPU`核心数带来的多线程性能提升,带来的能耗增加相比提升`IPC`、`时钟频率`更低。现在手机端`CPU`中也有`5-9`个核心,PC 级`CPU`中通常有`10-30`个核心,服务器`CPU`中核心数更多。 增加核心数可以复用核心内部的微架构设计,根据`CPU`的功耗、成本、性能诉求选择核心数量。例如`Intel`在桌面级酷睿处理器和服务器至强处理器可能会使用同样的核心,只是会增加更多的核心数量。`Apple`在`A`系列和`M`系列芯片也会使用同样的核心。 增加核心数也能带来一定的能耗优势,操作系统`内核`会根据运算负载动态的调度不同数量的核心进行执行,在运算负载低的时候可以调度更少的核心降低功耗。 ### `大小核` 现代`CPU`中通常还会使用`大小核`异构架构设计来提升能耗比降低功耗。`性能`核心用于高性能计算场景最大化执行性能,`能耗`核心用于日常低负载计算场景降低能耗。相同的核心会使用同样的`时钟频率`来运行,通常会共享使用`L2缓存`。`大小核`的设计也增加了操作系统`内核`对于多核心调度的难度。 ###### 性能核心、能效核心区别 | 类型 | 性能 | 功耗 | 时钟频率 | IPC | | :-: | :-: | :-: | :--: | :-- | | 性能核 | 高 | 高 | 更高的时钟频率 | 复杂的流水线设计、IPC 更高 | | 能耗核 | 中 | 中 | 更低的时钟频率 | 简单的流水线设计、IPC 更低(更少的解码宽度、没有动态调度、更少的计算单元等) | ###### 大小核设计 ![](https://img12.360buyimg.com/img/jfs/t1/225931/12/5659/12903/65700d2fF5956809e/182106e19e46b7bd.png) ## `小结` 近些年`CPU`通过增加更多的核心数量提高`CPU`的多线程并行能力,但是这也带来了一些新的问题限制了核心数一直快速增加。首先`CPU`核心数更多增加`缓存一致性`的复杂度会影响性能,`操作系统`内核如何更好的对更多核心进行调度达到最高的能耗比。 同时对于`软件开发者`来讲,利用越来越多的核心进行编程会更复杂。编程语言以及开发框架也需要进行调整利用更多的核心。同时对于不同的软件类型,可以利用多线程并行执行的部分也是不一样的。(如果一个程序只有`10%`的运算工作可以并行执行,即使添加更多核心带来的提升也很有限) 虽然增加核心数带来的能耗增加相比`IPC`、`时钟频率`更低,但是依然会增加功耗,`功耗墙`也是限制核心数增加的限制之一。 # `高速缓存和内存提升` 虽然内存不属于处理器内部的结构,但是处理器运行时会依赖内存中的程序指令和程序数据,所以内存性能对处理器性能的影响很大。因为内存性能提升相比处理器`时钟频率`提升非常缓慢,当前处理器对内存读写通常需要`50-100个`时钟周期。关于`内存访问速度`的提升,一个方向是通过引入`多级缓存`减少处理器对内存的直接访问,另一个方向是内存自身性能的提升。 ## `引入高速缓存` 为了减少处理器对内存的直接访问,现代处理器引入了`SDRAM(Synchronous dynamic random-access memory)`存储作为处理器的缓存集成在处理器芯片中。`SDRAM`的优点是访问速度比内存快很多,缺点是`功耗高`、`成本高`(1位需要 6-7 个晶体管)、`容量低`。 处理器对内存的所有访问都通过缓存进行加载,缓存会保存最近使用过的内存数据,这样下次访问这些数据时就可以直接从缓存中返回避免直接从内存中读取。 #### 内存读写过程 以下是一个简单的具有`二级缓存`的处理器内存读写过程原型,不过现代处理器设计通常会比这个过程更加复杂: ###### 读取 - `L1` - 处理器核心需要读取数据时,将数据内存地址发送给`L1缓存`。`L1缓存`检查是否有缓存数据,如果`L1缓存`中有缓存数据直接返回。如果缓存缺失将数据内存地址发送给`L2`。 - `L2` - `L2缓存`检查是否有缓存数据。如果`L2缓存`中有缓存数据将数据写入`L1缓存`同时读取到处理器中。如果缓存缺失将数据内存地址发送给`内存`。 - `内存` - 从内存中读取数据,之后分别写入`L2缓存`、`L1缓存`,然后读取到处理器中。 ###### 保存 处理器核心将寄存器中的数据保存到内存时,分别写入`L1缓存`、`L2缓存`,之后保存到内存中。 ### `缓存提升方向` 缓存性能提升方向主要是`提高缓存命中率`、`降低缓存缺失耗时`、`降低缓存命中耗时`,主要是通过以下这些技能进行提升: ##### 增加容量 增加缓存的容量,缓存中可以存储的数据越多,`缓存命中率`也就越高。功耗和成本会限制容量增长的速度,同时因为增加容量会影响访问速度,所以`L1`缓存容量增长很慢。 ##### 使用多级缓存 现代处理器通常有`2-3`级缓存,多核处理器每个核心包含一个`L1`缓存,`L2`、`L3`缓存是多个核心共享。读取速度`L1 > L2 > L3`,容量`L3 > L2 > L1`,成本`L1 > L2 > L3`。 这么设计的目的主要是通过`局部性原理`提高缓存性能。`L1`缓存关注读取性能,将更常用的内存数据放到容量更小的`L1`缓存中更快的读取。同时`L1`缓存设计会将`指令`和`数据`分离,提高缓存性能和缓存命中率。`L2`/`L3`缓存关注缓存缺失率,将更多的内存数据防止在缓存中减少`缓存缺失耗时`。 > `时间局部性` - 被引用过一次的内存数据在未来会被多次引用。 > `空间局部性` - 一个内存数据被引用,那么未来它临近的内存地址也会被引用。 ###### 现代`CPU`多级缓存设计 ![现代 CPU 多级缓存](https://img30.360buyimg.com/img/jfs/t1/224224/38/6966/15186/65700d8fF445eaff6/5cd939bda50b5d7e.png) > 提示:通常`L1缓存`是单核心独占、`L2缓存`可能是单核心独占或多核心共享、`L3缓存`/`内存`是所有核心共享。通过`MESI`协议来解决缓存一致性的问题。 ###### 多级缓存和内存性能 | 存储类型 | 访问速度 | 容量 | 功能 | | | :--: | :-----------: | :-----------: | :---: | :------------- | | L1 | 1 - 5 时钟周期 | 64 - 256 KB | 指令、数据 | - | | L2 | 10 - 20 时钟周期 | 512 KB - 2 MB | 数据 | A17 Pro 大核16MB | | L3 | 20 - 50 时钟周期 | 12 - 36 MB | 数据 | - | | DDR | 50 - 100 时钟周期 | 8 - 64 GB | 指令、数据 | - | ##### 降低缓存命中时间 通过更优秀的缓存涉及,减少缓存命中时的耗时。但是通常减少命中缓存耗时和增加缓存容量通常会有不可调和的矛盾。 ##### 缓存预加载 根据前面流水线的介绍,现代处理器通常会对一次性读取内存多条程序指令到放入缓存中,同时也会提前读取后面可能会使用的内存数据到缓存中。但是当提前预加载到缓存中的数据并没有使用到时,会造成额外的功耗浪费。(例如分支预测错误) ##### 优化缓存更新算法 将新的数据写入到缓存时,由于容量限制通常需要替换掉旧的缓存数据。常见的替换算法有`LRU`算法,使用更好的算法可以提高`缓存命中率`。 ## `内存性能提升` 虽然通过加入多级缓存可以提高内存读写的性能,但是处理器高速缓存的容量很有限,遇到缓存缺失时还是需要直接访问内存。所以对内存的性能提升依然很重要,内存性能提升主要是从以下四个方向进行提升: - `读取延迟` - 持续减少内存读取延迟,可以降低`缓存缺失`从内存中读取数据的耗时。 - `功耗` - 由于移动设备等低功耗场景的出现,对内存产生的`功耗`也有更低的要求。 - `带宽` - 因为内存性能提升很慢,同时现代处理器不断的引入新的协处理器例如`GPU`、`NPU`需要进行更多的内存数据传输。增加内存带宽虽然无法降低单次内存读取延迟但是可以同时传输更多的数据。 - `成本` - 更低的成本可以使商品价格更低,同时可以增加更多的内存容量。 ### `更多内存类型` 由于内存无法同时满足对`延迟`、`功耗`、`带宽`、`成本`的要求,现代内存逐渐发展出了多种不同的内存类型。针对不同的计算场景选择使用不同类型的内存,主要是基于处理器对`延迟`、`功耗`、`带宽`、`成本`的要求进行选择。每一代内存新标准的推出也会逐渐提高`延迟`、`功耗`、`带宽`的性能,同时降低上一代标准的`成本`。(通常新标准成本更高) ###### 不同内存类型特点 | 类型 | 最新标准 | 延迟 | 功耗 | 带宽 | 最大带宽 | 面积 | 成本 | 使用场景 | 特点 | | --- | --- | :-: | :-: | :-: | --- | :-: | :-: | --- | --- | | DDR | DDR5 | 低 | 中 | 低 | 64 Gbps | 中 | 低 | PC、服务器 | 延迟最低 | | LPDDR | LPDDR5X | 中 | 低 | 中 | 77 Gbps (8 Gen 3) | 小 | 低 | 手机、笔记本 | 功耗最低 | | GDDR | GDDR6X | 高 | 高 | 高 | 1008 Gbps(RTX 4090) | 大 | 中 | 独立显卡 | 高带宽、功耗最高、延迟最高 | | HBM | HBM3e | 高 | 中 | 超高 | 4800 Gbps(H200) | 小 | 高 | 服务器GPU | 带宽最高、成本最高 | ### `集成封装工艺提升` 现代面向移动场景的处理器通常会将`LPDDR`内存使用`3D`集成封装技术直接集成到处理器芯片上。优点是可以减少传输物理距离提高传输性能、降低功耗,缺点是无法灵活更换内存。 ###### 内存集成封装到处理器芯片上 ![集成封装](https://img13.360buyimg.com/img/jfs/t1/233871/35/5931/39785/65700dcdF579b982f/6dd9744c5da5b1e7.jpg) ## `小结` 近些年`高速缓存`技术发展逐渐放缓,同时`缓存缺失`是导致`流水线停顿`的主要原因之一。由于`读取延迟`限制了`L1`缓存容量的提升,`L1`容量提高很少。半导体工艺发展放缓,晶体管数量增长速度降低以及功耗问题,也降低了`L2`、`L3`缓存容量增加的速度。同时高速缓存的引入也给`编译器`和`软件开发者`带来了更大的挑战,如何更好的利用`局部性原理`提高`缓存命中率`:开发者需要编写`缓存命中率`更高的代码、编译器需要生成`缓存命中率`更高的程序指令。 > 提示:增加缓存容量的成本很高。以A17 Pro芯片为例,总共 190 亿个晶体管,因为包含`GPU`、`NPU`等协处理器,`CPU`使用的晶体管数量不超过 30%。缓存大小`L2 20MB + L1 192KB`,以一个缓存位需要几个晶体管来计算,缓存大概需要耗费几亿个晶体管。 内存技术每一代新标准在增加`带宽`、`容量`和`能耗比`上都有不错的提升,但是`读取延迟`降低缓慢很多。内存读取延迟导致的`内存墙`依然是限制处理器性能的主要因素之一。因为`内存墙`的限制,现在也有一种`存算一体`的探索方向,将内存和计算单元集成在一起减少数据传输延迟。 现代处理器核心数越来越多,每个核心都有自己的`L1`缓存,多个核心需要共享`L2`缓存、`L3`缓存、内存数据。多核`缓存一致性`的复杂度越来越高,额外的开销可能会降低`读取延迟`和`增加功耗`,限制`多核`处理器的性能。 > 提示:从高速缓存和内存上看,更小的程序体积、更小的内存占用是可以增加程序的运行性能的。 # `SOC、DSA 和 Chiplet` ## `SOC` `SOC`(System on Chip)片上系统是一种将多个不同模块封装在一个芯片中的技术。现代`CPU`基本上都属于`SOC`芯片,将`CPU`、`GPU`、`NPU`、`WIFI`、`蓝牙`、`Modem`等模块集成到同一个芯片中。由于半导体技术的发展可以集成在芯片上的晶体管数量越来越多,可以将更多的模块集成到一个芯片中带来`集成度`、`性能`、`系统单元复用率`的提升: | 模块 | 最新标准 | | --- | --- | | 提高性能 | 不同模块集成在同一个芯片上,跨模块间通信更快、功耗更低。手机端`SOC`通常会将内存封装在`SOC`芯片上,不同模块可以使用`统一内存`的方式复用内存,降低内存在不同模块间的传输提高性能。 | | 提高集成度 | 不同模块集成在同一个芯片上,相比传统多个模块芯片的设计可以复用重复的传输电路或内存等`降低成本`、`降低面积`、`降低功耗`。(例如传统`CPU`/`GPU`都有独立内存,封装到`SOC`中可以复用一个内存即可。) | 虽然带来了性能的优势,但是由于`SOC`集成了更多模块同时需要模块间互联,芯片设计、制造复杂度更高,导致成本也更高。 ### `SOC 组成结构` 现代`SOC`通常由一个CPU单元、多个协处理器(NPU/GPU)、无线模块(WIFI/蓝牙/蜂窝网络)、多媒体单元(ISP、DSP)、内存控制器、I/O 单元组成: | 模块 | 功能 | | --- | --- | | CPU | 中央处理器 | | GPU | 图形渲染、高性能运算 | | NPU | 神经网络运算、端测 AI 加速 | | ISP | 相机传感器、拍照/视频图像信号处理、优化画面质量 | | DSP | 音视频/图片硬件编解码 | | 无线 | WIFI、蓝牙、蜂窝网络的传输通讯、协议编解码、连接管理 | | Display Engine | 管理屏幕显示、图像数据转换为屏幕格式、图像效果/分辨率优化、帧率调整 | | 内存控制器 | 内存读写、内存地址映射、内存一致性、统一内存复用 | | I/O | 管理输入/输出设备的 I/O 读写 | ###### 高通 8 gen 3 ![Qualcomm_SoC](https://img13.360buyimg.com/img/jfs/t1/232123/34/6562/25607/65700e2fFcf808d2f/63a7cbbba3d2b93b.jpg) - `Hexagon Processor` - AI 模块 - `FastConnect` - WIFI、蓝牙 ###### Apple M3 ![M3](https://img12.360buyimg.com/img/jfs/t1/237896/10/5573/231720/656d59afF8dcf4995/2d57da8021631d76.jpg) - 从`M3`的设计上可以看出,现代`SOC`中`CPU`部分占用的硅面积不超过`30%` ## `DSA` `DSA`(Domain Specific Architecture)领域特定架构是一种用于特定领域计算的结算机体系。由于`CPU`是一种追求通用计算的计算机体系结构,对于特定领域计算(音视频、图形、AI 等)的性能和能效比都比较差。`DSA`通过面向特定领域计算的设计大幅提高性能和能耗比,解决`CPU`对于特定领域计算的性能劣势。 ### `DSA 设计` 现代`SOC`中的`GPU`、`NPU`、`DSP`就是一种常见的`DSA`模块。传统`CPU`通过复杂流水线设计、高速缓存、增加寄存器位数等特性提高`CPU`的运算性能,但是这会导致大量的晶体管消耗增加成本和能耗。`DSA`通过减少这些复杂的设计提高晶体管的利用率提高能效,相比`CPU`执行同样的特定领域运算可以带来的优势:更小的面积、更低的成本、更高的能耗比、更好的性能。 ###### DSA 设计原则 | 特点 | 说明 | 备注 | | --- | --- | :-: | | 专用存储 | 使用专用存储器减少数据移动 | - | | 最小化数据类型 | 使用更小位宽的数据类型来计算、节省存储空间、运算更快 | - | | 更多运算单元或存储器 | 加入更多运算单元、更大的存储器 | - | | 并行方式 | 选择更有利于特定领域计算的并行方式 | 例如 GPU 的并行方式 | | 专用编程语言 | 使用面向特定领域计算的编程语言/框架进行编程 | - | ## `Chiplet` `Chiplet`是近几年发展出的一种将不同的功能模块分离成小芯片,并通过先进封装技术组合在一起的新技术。`Chiplet`主要是为了解决传统`SOC`遇到的`成本高`和`扩展性`问题。 | 特点 | 说明 | 备注 | | --- | --- | :-: | | 降低成本 | 不同芯片可以使用不同成本的工艺制造、小芯片可以复用降低设计成本、小芯片面积更小成本更低 | - | | 灵活性、扩展性 | 根据诉求灵活集成不同的小芯片满足市场需求、3D 封装降低芯片面积 | - | 不过`Chiplet`对封装技术的要求很好,不同小芯片间的通信设计也很复杂。目前只有少量的芯片使用了这种方式进行芯片制造。 ###### Meteor Lake ![Meteor Lake](https://img13.360buyimg.com/img/jfs/t1/235579/31/6152/2173626/65700e55F09aacd03/8c97b5725156b50f.jpg) - `Intel`2023年推出的`Meteor Lake`处理器使用`Chiplet`封装,`CPU`使用Intel`4nm`工艺,`Graphics`使用台积电`5nm`工艺,`SOC`、`IO`使用台积电`6nm`工艺。 ## `小结` 由于`CPU`通用处理器性能提升放缓和对特性领域计算的能耗比和成本问题,未来也许会加入更多的`DSA`模块用于提升特定领域计算的性能和能耗比。近些年`PC`端处理器也在效仿`移动端`处理器加强`DSA`单元能力,包括提高核显 GPU 的性能以及加入 NPU。同时`Chiplet`技术的发展也可以帮助处理器集成更多的`DSA`单元同时降低成本。 # `主流 CPU 发展` ## `Intel 处理器发展` | CPU | 频率 | 核心数 | 线程数 | 指令集 | 微架构 | 工艺 | 晶体管数量 | TDP | 发行年份 | 备注 | | :-- | :-- | :-- | :-- | :-- | :-- | --: | --: | :-: | :-: | :-: | | Core i9-14900K | 3.2 - 6 GHz | 8 + 16 | 32 | x86-64 | Raptor Cove + Gracemont | 7 nm | - | 125 - 253W | 2023 | - | | Core i9-13900K | 3 - 5.8 GHz | 8 + 16 | 32 | x86-64 | Raptor Cove + Gracemont | 7 nm | - | 125 - 253W | 2022 | - | | Core i9-12900K | 3.2 - 5.2 GHz | 8 + 8 | 24 | x86-64 | Golden Cove + Gracemont | 7 nm | - | 125 - 241W | 2021 | 引入大小核混合架构、支持 DDR5 | | Core i9-11900K | 3.5 - 5.3 GHz | 8 | 16 | x86-64 | Cypress Cove 待确定 | 10 nm | - | 95 - 125 W | 2021 | - | | Core i7-6700K | 4 - 4.2 GHz | 4 | 8 | x86-64 | Skylake | 14 nm | - | 91 W | 2015 | - | | Core i7-4790K | 4 - 4.4 GHz | 4 | 8 | x86-64 | Haswell | 22 nm | - | 88 W | 2014 | - | | Core i7-990X | 3.4 - 3.7 GHz | 6 | 12 | x86-64 | Westmere | 32 nm | 12 亿 | 130 W | 2011 | - | | Core 2 E6700 | 2.66 GHz | 2 | 2 | x86-64 | Conroe | 65 nm | 2.9 亿 | 65 W | 2006 | 引入双核心 | | Pentium D Processor 840 | 3.2 GHz | 2 | 2 | x86-64 | NetBurst | 90 nm | 2.3 亿 | - | 2005 | - | 引入x86-64 指令集 | | Pentium 4 Extreme Edition | 3.4 GHz | 1 | 2 | x86-32 | NetBurst | 130 nm | - | 110W | 2004 | 引入超线程 | | Pentium 4 2.8 GHz | 2.8 GHz | 1 | 1 | x86-32 | NetBurst | 130 nm | 5500 万 | - | 2002 | - | | Pentium 3 Processor 1.1 GHz | 1.1 GHz | 1 | 1 | x86-32 | P6 | 180 nm | - | 33 W | 2000 | - | | Pentium Pro 200 MHz | 200 MHz | 1 | 1 | x86-32 | P6 | 500 nm | 550万 | 35W | 1995 | 微解码转换、动态调用、乱序执行、推测执行、引入二级缓存、SSE、支持寄存器更名 | | Pentium | 60 MHz | 1 | 1 | x86-32 | P5 | 800 nm | 310 万 | - | 1993 | - | 第一个超标量处理器、1周期2指令、2解码器、代码数据缓存分离、分支预测、TDP14.6、面积294mm | | 80486 | 25 MHz | 1 | 1 | x86-32 | i486 | 1 um | 100万 | - | 1989 | - | 集成浮点单元、引入一级缓存 | | 80386 | 20 MHz | 1 | 1 | x86-32 | - | 1.5 um | 27.5万 | - | 1985 | 加入6级流水线 | | 80286 | 12.5 MHz | 1 | 1 | x86-16 | - | 1.5 um | 13.4 万 | - | 1982 | - | | 80186 | 6 MHz | 1 | 1 | x86-16 | - | 2 um | 5.5 万 | - | 1982 | - | | 8086 | 5 MHz | 1 | 1 | x86-16 | - | 3 um | 2.9 万 | 2 W | 1978 | 第一个 x86 架构处理器、16 位、引入8个通用寄存器、分段内存 | | 8085 | 3 MHz | 1 | 1 | 8085 | - | 3 um | 6500 | - | 1976 | - | | 8080 | 2 MHz | 1 | 1 | 8080 | - | 6 um | 4500 | - | 1974 | 不兼容 8008 | | 8008 | 0.5 MHz | 1 | 1 | 8008 | - | 10 um | 3500 | 1 - 2 W | 1972 | 第一个 8 位可编程处理器 | ## 最新 CPU 微架构对比 | 代号 | 类型 | 指令集 | 线程数 | 解码宽度 | ROB | 发射宽度 | 分支预测惩罚 | L1 缓存 | L2 缓存 | SIMD | IPC | | :-: | :-: | :-- | :-- | --- | --- | --- | --- | --- | --- | --- | --- | | Raptor Cove | Intel 性能核 | x86-64 | 2(超线程) | 6 | 512 | 6 | 8 | 48 KB(D)、32 KB(I) | 2 MB | AVX 512 | 3.525、4.23(超线程) | | Gracemont | Intel 能效核 | x86-64 | 1 | 6 | 256 | 6 | 8 | 32 KB(D)、64 KB(I) | 2 MB(共享) | AVX 256 | 2.52 | | A520 | ARM 小核 | ARMv9 | 1 | 3 | 0 | 3 | - | 64 KB(D)、32 KB(I) | 256 KB | SVE | 0.94 | | A720 | ARM 大核 | ARMv9 | 1 | 5 | 192 | 5 | - | 64 KB(D)、32 KB(I) | 512 KB | SVE | 3.03 | | X4 | ARM 超大核 | ARMv9 | 1 | 10 | 384 | 10 | - | 64 KB(D)、64 KB(I) | 2 MB | SVE | 4.4 | | A17 E | Apple 能效核 | ARMv8 | 1 | 5 | 224 | 5 | 5 | 128 KB(D) + 64 KB(I) | 4 MB(共享) | NEON | 3.05 | | A17 P | Apple 性能核 | ARMv8 | 1 | 9 | 670 | 9 | 9 | 64 KB(D)、128 KB(I) | 16 MB(共享) | NEON | 5.06 | # `对开发者的影响` ## `更多核心数` `CPU`核心数越来越多,软件开发者需要使用面向多线程的利用更多的核心并行才能提高程序执行的性能。同时也可以导致编程语言、编程范式、框架的一些改变: - `多线程编程` - 更多的使用到多线程编程利用多核的性能 - `简化并行编程` - 编程语言提供了更多特性简化并行编程,例如`async/await`函数、结构化并发 - `异步编程` - 更多的跨线程异步调用 - `非共享内存的并发模型` - 可以减少数据竞争、减少线程锁使用、减少线程切换的耗时,`Go`、`Rust`、`Swift`语言都提供了类似的并发模型 - `UI框架` - 传统`UI`框架都是基于单线程模型设计,`UI`框架和`浏览器`需要更好的利用多核心的性能优势。同时非`UI`操作需要更多考虑多线程的利用减少主线程的消耗 - `函数式编程` - 函数式编程更有利于并行执行变得更流行 ## `SIMD、DSA单元` `SOC`不断增加更多的`DSA`单元增加特定领域运算的能耗比,未来可能需要面向更多不同类型的处理器进行编程,不同的处理器会导致编程语言和编程范式的改变。 ## `硬件性能提升放缓` `CPU`性能提升放缓带给软件的性能提升更少,同时软件自身功能不断增加对于性能的消耗,软件追求更高的性能提升就需要做更多的软件性能优化。 - `AOT` - 类似`Java`、`C#`、`JS`这些传统的解释执行编程语言开始追求`AOT`编译提高性能,新的编程语言通常也会支持`AOT`编译 - `简化内存管理` - 简化传统的自动内存管理方式,使用更简单的内存管理方式。例如`Rust`的所有权更多利用编译器去检查内存安全 - `值类型` - 更多的值类型使用,栈上的值类型性能更好 - `编译器` - 编译器利用静态优化生成性能更好的代码减少运行时消耗,静态类型系统、静态方法派发 # 相关链接 - [计算机组成与设计:硬件/软件接口 RISC-V版(原书第2版)](https://book.douban.com/subject/36490912/) - [计算机体系结构:量化研究方法(第6版)](https://book.douban.com/subject/36108789/) - [ARM64体系结构编程与实践](https://book.douban.com/subject/35803160/) - [芯片战争](https://book.douban.com/subject/36350632/) - [芯片简史](https://book.douban.com/subject/36357053/) - [Introducing the Arm architecture](https://developer.arm.com/documentation/102404/0201) - [Arm A-Profile Architecture](https://developer.arm.com/Architectures/A-Profile%20Architecture) - [Arm A64 Instruction Set Architecture](https://developer.arm.com/documentation/102374/0101) - [Arm A-profile A64 Instruction Set Architecture](https://developer.arm.com/documentation/ddi0602/2023-09/Base-Instructions?lang=en) - [AArch64 memory management](https://developer.arm.com/documentation/101811/latest) - [Snapdragon 8 Gen 3 Mobile Platform](https://www.qualcomm.com/products/mobile/snapdragon/smartphones/snapdragon-8-series-mobile-platforms/snapdragon-8-gen-3-mobile-platform) - [Snapdragon X Elite](https://www.qualcomm.com/products/mobile/snapdragon/pcs-and-tablets/snapdragon-x-elite) - [NanoReview](https://nanoreview.net/) - [Geekbench](https://browser.geekbench.com/) - [Intel Core i9-14900K](https://www.intel.cn/content/www/cn/zh/products/sku/236773/intel-core-i9-processor-14900k-36m-cache-up-to-6-00-ghz/specifications.html) - [Intel Core i9-10900K](https://www.intel.cn/content/www/cn/zh/products/sku/199332/intel-core-i910900k-processor-20m-cache-up-to-5-30-ghz/specifications.html) - [Intel Core 2 E6700](https://ark.intel.com/content/www/cn/zh/ark/products/27251/intel-core2-duo-processor-e6700-4m-cache-2-66-ghz-1066-mhz-fsb.html) - [Pentium 4 Processor Extreme Edition](https://ark.intel.com/content/www/us/en/ark/products/27491/pentium-4-processor-extreme-edition-supporting-ht-technology-3-46-ghz-2m-cache-1066-mhz-fsb.html) - [Intel Pentium III Processor 1.1 GHz](https://www.intel.cn/content/www/cn/zh/products/sku/27530/intel-pentium-iii-processor-1-10-ghz-256k-cache-100-mhz-fsb/specifications.html) - [Intel Pentium Pro 200 MHz](https://www.intel.cn/content/www/cn/zh/products/sku/49951/intel-pentium-pro-processor-200-mhz-1m-cache-66-mhz-fsb/specifications.html?wapkw=Pentium%20Pro) - [80486](https://en.wikipedia.org/wiki/Intel_80486) - [80386](https://en.wikipedia.org/wiki/Intel_80386) - [80286](https://en.wikipedia.org/wiki/Intel_80286) - [80186](https://en.wikipedia.org/wiki/Intel_80186) - [8086](https://en.wikipedia.org/wiki/Intel_8086) - [Intel Processors](https://en.wikipedia.org/wiki/List_of_Intel_processors) - [CPU 微架构设计](https://drive.google.com/drive/folders/1W4CIRKtNML74BKjSbXerRsIzAUk3ppSG?usp=sharing)
上一篇:一行代码修复100vh bug
下一篇:最佳实践 | 京东小程序-LBS业务场景的性能提升
29****
文章数
6
阅读量
2029
作者其他文章
01
基于 prefetch 的 H5 离线包方案
前言对于电商APP来讲,使用H5技术开发的页面占比很高。由于H5加载速度非常依赖网络环境,所以为了提高用户体验,针对H5加载速度的优化非常重要。离线包是最常用的优化技术,通过提前下载H5渲染需要的HTML/JS/CSS资源,加载时直接使用本地缓存资源避免额外的网络请求提高加载速度。本文主要是介绍团队在离线包技术方案上的探索,以及基于prefetch的离线包实现方案如何减少维护成本和开发成本。现有方
01
京喜APP - 图片库优化
介绍京喜APP早期开发主要是快速原生化迭代替代原有H5,提高用户体验,在这期间也积累了不少性能问题。之后我们开始进行一些性能优化相关的工作,本文主要是介绍京喜图片库相关优化策略以及关于图片相关的一些关联知识。图片性能问题作为电商APP,图片在各个业务场景被大量使用。我们需要做到尽可能降低网络消耗/内存消耗/硬盘消耗,同时不降低图片质量,提高图片加载速度,给用户带来更好的使用体验。基于这些性能目标,
01
使用Swift提高代码质量
前言京喜APP最早在2019年引入了Swift,使用Swift完成了第一个订单模块的开发。之后一年多我们持续在团队/公司内部推广和普及Swift,目前Swift已经支撑了70%+以上的业务。通过使用Swift提高了团队内同学的开发效率,同时也带来了质量的提升,目前来自Swift的Crash的占比不到1%。在这过程中不断的学习/实践,团队内的Code Review,也对如何使用Swift来提高代码质
01
移动端APP组件化架构实践
theme: smartblue前言对于中大型移动端APP开发来讲,组件化是一种常用的项目架构方式。个人最近几年在工作项目中也一直使用组件化的方式来开发,在这过程中也积累了一些经验和思考。主要是来自在日常开发中使用组件化开发遇到的问题以及和其他开发同学的交流探讨。本文通过以下问题来介绍组件化这种开发架构的思想和常见的一些问题:为什么需要组件化组件化过程中会遇到的挑战和选择如何维护一个高质量的组件化
29****
文章数
6
阅读量
2029
作者其他文章
01
基于 prefetch 的 H5 离线包方案
01
京喜APP - 图片库优化
01
使用Swift提高代码质量
01
移动端APP组件化架构实践
添加企业微信
获取1V1专业服务
扫码关注
京东云开发者公众号