轻松读懂应用处理器微架构 版0109.docx
《轻松读懂应用处理器微架构 版0109.docx》由会员分享,可在线阅读,更多相关《轻松读懂应用处理器微架构 版0109.docx(20页珍藏版)》请在冰豆网上搜索。
轻松读懂应用处理器微架构版0109
轻松读懂“应用处理器”微架构2013版
第1页:
什么是应用处理器?
对不起,你被标题欺骗了,实际上对许多读者来说要读懂本文并不是那么轻松:
p
随着半导体工艺的日趋先进,智能手机(Smartphone或者Superphone)、平板电脑(Tablet或者Pad)已经成为许多网友最常使用、最多关注、更新最快的电子消费产品,高度便携性是这类产品的最关键成功原因。
所谓便携性自然是指产品必须足够轻便而且需要有足够的续航能力,因此这就要求产品的原件必须足够省电,只有这样才能减少散热和电池体积这两个最占体积和重量的问题。
要达到这个目标,肯定要做功能和性能上的妥协,至少相对个头更大的笔记本电脑、台式机而言,像降低吞吐率或者增加时延,从实测性能而言,目前智能手机或者平板电脑的CPU、图形处理器性能基本上相当于6到10年前台式电脑的水准。
举个简单的例子,在俄罗斯网站ixbt的讨论区上,有这样的一条帖子,一位名为ssvb的网友采用origenboard.org的一片SamsungExynos4210开发板(配有Exynos4210处理器具备两个ARMCortex-A9处理器内核)跑出来的HighPerformanceLinpack(HPL)性能是1.307GFLOPS,同贴中还有IntelAtomN450(Pineview架构,45nm,单核)1.66GHz的测试结果——0.944GFLOPS以及Cortex-A151.7GHz双核HPL为4.3GFLOPS。
NVIDIA官网上的一份SC011文件也表明Tegra2(ARMCortex-A9双核1GHz,理论双精度浮点性能2GFLOPS)的HPL性能为1.15GFLOPS(57%效率,200MFLOPS/瓦)。
这都是一个什么概念?
我曾经在06年的时候用PentiumD8202.8GHz跑出来的HPL性能为10.12GFLOPS,Athlon64X22.6GHz为9.158GFLOPS。
那么现在台式机的HPL性能状况如何?
在去年我用Corei72600K3.4GHz配合未支持AVX指令的GotoBLAS(数学库)上得到的HPL性能为51.18GFLOPS左右,后来又用支持AVX的OpenBLAS(原GotoBLAS开发者停止更新后的其中一个后续开源社区版)得出的HPL性能为99.38GFLOPS,到2013年支持AVX2指令集的Haswell架构出来后,这个测试结果应该还能接近再翻番,达到200GFLOPS级别。
也许你会说手机、平板要双精度干啥呢?
请不要忘记在30年前的x86处理器根本没有集成任何硬件浮点单元,现在的情况又如何?
曾经做出号称最强x87协处理器的Cyrix后来一头扎进整数为王的产品策略后现在影都没了。
“干啥”这个问题往往是硬件具备并达到一定性能条件后就会有答案的,台式机上的性能测试软件和方案会随着手机、平板性能日益强大而变得在这类设备上运行也理所应当,除了上面说的HPL外,各类PC上流行的测试工具例如SPECCPU20xx、3DMark等也会是如此。
传统的CPU性能测试的确不能完全适用于手机、平板的SoC芯片(人们把可以在移动操作系统上跑应用软件的SOC称作应用处理器,简称AP),但是请注意我说这句话是因为SoC并不仅仅有CPU,还有GPU、音视频编解码器、存储控制器、非易失性存储单元、数模/模数转换器以及各种输入输出周边等,这使得我们要单纯评价一款SoC是否最佳的时候可能会感到颇为伤神。
话虽如此,不过总的来说,SoC中和性能最密切相关的依然是CPU、GPU,因为智能设备里几乎所有程序的运行都必须依仗两者来执行,与用户的使用感受有直接关系(请注意,我们这里说的只是指SoC芯片中,而非手机或者平板电脑整体)。
因此,纵然手机、平板处理器型号各异并且内中千头万绪,我们还是应该从大家最关心的CPU、GPU着手来了解。
现在情况简单多了,按照ISA(指令集架构)划分,因为目前的手机、平板CPU无非是ARM、Intel/AMD两大阵营,潜在的还有MIPS,不过目前MIPS似乎在这个领域还成不了气候,更像是一个备胎。
如果你对计算机科学还不是很了解的话,对ISA这个词可能也不会很了解,虽然它经常出现在一些时髦的技术文章中。
电脑显然并不能直接明白C、Java、Basic这样的高级语言(虽然有人尝试过开发高级语言处理器,但是无不失败告终),搭建在高级语言和CPU本机代码之间的就是ISA。
ISA的全称是instructionsetarchitecture,中文就是指令集架构,有时候直接称呼为架构(architecture),是指程序员实际“可见”的指令集,包含了程序员编写一个能正确运行的二进制机器语言程序的所有信息,涉及到指令、I/O设备等。
例如Intel的IA-32、Intel64(曾经名为IA32e、EM64T等);ARM的ARMv7、ARMv8等等。
这里的IA32、Intel64或者ARMv7、ARMv8其实是指各自指令集架构的不同版本,有时候我们嫌啰嗦,所以把前两者统称x86,后两者统称ARM。
将ISA变成真正可以使用的实物需要经过“实现”,它包括两个层面:
组成和硬件。
组成是从计算机设计的高阶层面而言,例如:
存储系统、存储互连接、CPU(包括算术、逻辑分支、数据传输的实现)设计,有时候“组成”又被称作微架构(microarchitecture),英特尔Nehalem、NVIDIAKepler、ARMCotrex-A57都可以属于各自某系列芯片的微架构,其中Kepler的ISA是CUDAPTX和Cortex-A57的ISA属于ARMv8。
硬件通常是指电脑的规格,包括具体的逻辑设计、封装技术,同一系列的产品可能有相同的ISA、近乎一样的微架构,但是存在某些具体规格的差别,例如NVIDIATegra3,有AP30、AP33、T30、T33、T30S、T33S、T30SL等具体的型号,它们都属于Tegra3微架构,但是频率规格、内存规格等地方都有差别。
而GPU方面则复杂一些,有PowerVR、高通、NVIDIA、ARM、Intel等等,其中使用最广泛的就是PowerVR,这得益于PowerVR10年前就决定全面切换到移动设备上,铺桥搭路的功夫很扎实,而NVIDIA和Intel的商业模型都是只用于自家产品(当然NVIDIA也曾经在游戏机领域做过RSX这样的IPcore授权)的,所以目前未能在其他SoC上看到。
下面的表格给出了这两年来比较热门的手机或者平板电脑ARM处理器,它们基本上都被应用于各公司的旗舰级产品中。
2011/2013SoC对比表
SoC
制程
CPU
GPU
内存总线
发布时间
AppleA5
45nm/32nm
2xARMCortexA9w/MPE@1GHz
PowerVRSGX543MP2
2x32-bitLPDDR2
2011-10-4
AppleA5X
45nm
2xARMCortexA9w/MPE@1GHz
PowerVRSGX543MP4
4x32-bitLPDDR2
2012-3-16
AppleA6
32nm
2xAppleSwift@1.3GHz
PowerVRSGX543MP3
2x32-bitLPDDR2
2012-9-12
AppleA6X
32nm
2xAppleSwift@1.4GHz
PowerVRSGX554MP4
4x32-bitLPDDR2
2012-10-23
NVIDIATegra2
40nm
2xARMCortexA9@1GHz
ULVGeForceT2
1x32-bitLPDDR2
2010-1-8
NVIDIATegra3/Kal-El
40nm
4xARMCortexA9w/MPE@~1.3GHz
ULVGeForceT3
1x32-bitLPDDR2
2011-11-8
NVIDIATegra4/Wayne
28nm
4xARMCortexA15MPCorew/MPE
ULVGeForceT4
2x32-bitLPDDR2
2012-1
SamsungExynos4210
45nm
2xARMCortexA9w/MPE@1.2GHz
ARMMali-400MP4
2x32-bitLPDDR2
2011-2-10
SamsungExynos4212
32nm
2xARMCortexA9w/MPE@1.5GHz
ARMMali-400MP4
2x32-bitLPDDR2
2011-10-1
SamsungExynos5250
32nm
2xARMCortexA15MPcorew/MPE@1.7GHz
ARMMali-604
2x32-bitLPDDR2
2011-11-30
QualcommMSM8060/8260/8660
45nm
2xScorpion@1.5GHz
Adreno220
1x32-bitLPDDR2*
2011-2-10
QualcommMSM8960
28nm
2xKrait@1.5GHz
Adreno225
2x32-bitLPDDR2
2011-2-14
QualcommMSM8960T
28nm
2xKrait@1.7GHz
Adreno320
2x32-bitLPDDR2
2012-2-27
QualcommAPQ8064
28nm
4xKrait@1.7GHz
Adreno320
2x32-bitLPDDR2
2011-2-14
它们都属于ARMv7架构,架构寄存器数量为16个,其中Tegra2/3、Exynos、A5/A5X的CPU核心是CortexA9或者CoretxA15,都是来自于ARM的IPcore授权,而A6/A6X的Swift和高通的Scorpion/Krait则分别是苹果和高通获得ARM架构授权后而各自自行开发的。
众所周知,IPcore的全称是IntellectualProertycore,意即知识产权内核,是目前各种嵌入式应用、个人智能消费类设备中最为常见技术类型,数十亿计的产品都采用了来自ARM、MIPS的IPcore。
IPcore被设计成可以和芯片中其他逻辑单元(例如视频编解码器、I/O界面、内存界面)协同运作形成一枚可以支持特定应用的处理器。
IPcore分为两类:
硬核(hardcore......不要会错意了)和软核(softcore)。
硬核是针对特定半导体厂商而优化的,对外人来说是一个提供了外部界面、不修改的“黑盒子”,获得授权的厂商通常只能对核外的逻辑参数进行修改,例如L2cache大小,但是IPcore本身不可修改。
而软核的设计代码则是可以针对不同半导体厂商做编译和修改,当然这要求设计厂商具备强大的研发实力和经验,因为现在的IPcore相当复杂。
简而言之而言,硬核的性能更高、占用管芯面积更小,而软核则可以让不同厂商作进一步的修改。
第2页:
长话短说“微架构”——流水线
ISA的“实现”需要借助各种微架构,现在的处理器微架构基本上涉及以下部分:
流水线化
多核、多线程
SIMD向量
存储系统分层结构
流水线
早期一些采用非常简单的指令集(注意,我们说的不是RISC)的电脑是采用单周期设计的,取指、解码、执行、写回都是放在同一个拍(周期)内顺序完成,此时的CPI(每指令周期数)基本上是1,但是这样设计的效率很低:
当取指的时候,其余工位都只能瞎瞪眼等开饭,这样的设计也被称作非流水线化执行。
上:
非流水线化(顺序化)执行
下:
流水线化执行
流水线化则是实现各个工位不间断执行各自的任务,例如同样的四工位设计,指令拾取无需等待下一工位完成就进行下一条指令的拾取,其余工位亦然。
世界上第一台采用流水线化指令执行的电脑为1961年的IBMStretch或者说IBM7030,具备四级流水线工位,它同时也是IBM第一台晶体管化电脑。
这样原本四工位非流水线的一个周期是800个皮秒的话,在流水线设计的处理器上,虽然同样的指令完成时间依然是800皮秒,但是第二条指令则可能只需要在第一条指令完成时间加200皮秒即第1000皮秒就能完成,而非流水线设计则需要第1600皮秒才能完成。
常见的五周期(FDEMW)流水线形式,对同步处理器来说Latch之间为一拍(周期)
对Pentium4这类异步处理器来说,个别工位(simpleALU)频率为双倍即1/2拍
RISC指令集具备指令编码格式统一、等长的特点,在流水线设计设计上有得天独厚的优势,这样可以使得流水线工位设计相对于指令编码格式不统一、非等长的CISC(例如x86的指令长度为1个字节到17个字节不等)来说显得更容易。
x86可能需要将一些工位拆开(这意味着流水线工位更多或者流水线长度更深),例如英特尔的第一款流水线化处理器——486的指令解码就是拆成两个工位。
流水线设计可以让指令完成时间更短(理论上受限于流水线执行时间最长的工位),因此将一些工位再拆开的话,虽然依然是每个周期完成一条指令,但是“周期”更短意味着指令吞吐时间进一步缩短,每秒能跑出来的指令数更多,这就是超级流水线的初衷。
微架构
(Microarchitecture)
流水线工位数
(Pipelinestages)
SonyCellPPU
23
IBMPowerPC7
17
IBMXenon
19
AMDAthlon
10
AMDAthlonXP
11
AMDAthlon64
12
AMDPhenom
12
AMDOpteron
15
ARM7TDMI(-S)
3
ARM7EJ-S
5
ARM810
5
ARM9TDMI
5
ARM1020E
6
XScalePXA210/PXA250
7
ARM1136J(F)-S
8
ARM1156T2(F)-S
9
ARMCortex-A5
8
ARMCortex-A8
13
AVR32AP7
7
AVR32UC3
3
DLX
5
IntelP5(Pentium)
5
IntelP6(PentiumPro)
14
IntelP6(PentiumIII)
10
IntelNetBurst(Willamette)
20
IntelNetBurst(Northwood)
20
IntelNetBurst(Prescott)
31
IntelNetBurst(CedarMill)
31
IntelCore
14
IntelAtom
16
LatticeMico32
6
R4000
8
StrongARMSA-110
5
SuperHSH2
5
SuperHSH2A
5
SuperHSH4
5
SuperHSH4A
7
UltraSPARC
9
UltraSPARCT1
6
UltraSPARCT2
8
WinChip
4
LC220032bit
5
例如Cortex-A15、SandyBridge都分别具备15级、14级流水线,而IntelNetBurst(Pentium4)、AMDBulldozer都是20级流水线,它们的工位数都远超出基本的四(或者五)工位流水线设计。
更长的流水线虽然能提高频率,但是代价是耗电更高而且可能会有各种性能惩罚。
第3页:
长话短说“微架构”——超标量
既然流水线设计可以实现不间断取指、解码、执行、写回,那为何不干脆同时做几条流水线一起取指、解码、执行、写回呢?
这就引出了超标量设计。
上图就是一个三路超标量四工位流水线的指令/周期执行示意图,可以看到CPI从1变成0.33,即每周期执行3.33条指令,这样的改进幅度是令人着迷的,因此在初期的时候超标量甚至被人们赞美为标量程序的向量式处理。
不过在现实中不可能都这样,因为现在的处理器执行不同指令时候的“执行”段工位并不完全一样,例如整数可能短一些,浮点或者向量和Load/Store指令需要长一些,加上一些别的因素,实际大部分程序的实际CPI都是1.x甚至更高啊。
例如:
a=b*c
d=a+1
这里的第二条指令需要使用到第一条指令的计算结果,因此必须等待第一条指令完成后才能跑第二条指令,更重要的是,在不少处理器上乘法指令并非一个周期而是需要多个周期才能完成。
在遇到这样的情况时,就不能实现多指令发射而且会出现流水线停顿。
第4页:
长话短说“微架构”——分支(转移)预测
当然,还有更复杂的情况:
if(a>5)
b=c;
else
b=d;
将其按照汇编语言编写出来:
cmpa,5;a>5?
bleL1
movc,b;b=c
brL2
L1:
movd,b;b=d
L2:
...
这里的第二条指令是一个条件分支指令(ble是小于或等于转移指令,bleL1表示如果寄存器a小于等于5就转移到L1这行执行movd,b这条指令)。
这条指令抵达“执行单元”的时候,位于流水线前段的取指单元和解码单元肯定已经拾取和解码了若干条指令,但是哪一条指令才应该接下来被执行呢?
应该是第三、四条还是第五条呢?
在第二行的条件分支指令完成之前,处理器只能等待。
处理器平均六条指令就会遇到一条分支指令,因此流水线设计带来的大部分性能提升优势此时会被丧失掉。
为此处理器必须进行“猜测”,按照猜测结果进行取指并推测哪些指令能开始执行,不过这些指令的执行结果并不会被递交(写回)直到分支指令的执行结果完成。
如果猜错的话,这部分指令的结果就会被扔掉,这也意味着这些指令对应的时间或者周期数会被浪费掉。
当然如果猜中的话,处理器就能全速运行了。
那么如何去做“猜测”呢?
一个办法是所谓的静态分支预测,例如在指令编码格式里留出一个位元作为预测信息,编译器编译的时候,对这个位元进行标记,告诉处理器该跑那条分支,不过这对于已经采用了不具备这类条件执行指令的旧式ISA二进制程序来说这样显然是不可能的。
另一个办法就是“运行过程中”进行猜测即动态分支预测,通常是采用类似被称作“片上分支预测表”的单元来记录最近分支的地址以及用一个位元指示出哪一条分支是最近是否被采用的。
不过现在大多数处理器实际上是用两个位元来作标记的,因此单次的分支“不跳转”并不会马上导致一般的“跳转”预测出现反转(这对于循环边界来说是很重要的)。
不过两位元分支预测并有考虑到分支相关性,所以人们后来有采用两级分支预测来解决这个问题,使得预测精度大大提高。
动态分支表需要占用相当可观的芯片面积,但是另一方面来说分支预测对流水线化处理器是相当重要的,所以是物有所值的。
不过就算是最好的分支预测技术也可能会猜错,对于超级流水线或者说深流水线来说就会有很多指令的结果会被扔掉,这样的情况被称作mispredictpenalty(误预测性能惩罚)。
像PentiumIII这类具备非常先进分支预测技术的处理器,在遇到分支预测失败的时候,也会出现10~15个周期的性能损失,因此即使正确命中了90%的分支,也会因为分支误预测导致30%的性能损失,所以PentiumIII其实很多时候会出现30%的时间在走冤枉路。
人们在ISA中引入条件执行指令(predicatedinstruction),希望籍此尽量减少分支,例如上面的例子,引入名为cmovle的判定指令后,可以写成这样:
cmpa,5;a>5?
movc,b;b=c
cmovled,b;ifle,thenb=d
cmovle的作用是“当小于或者等于的时候就进行赋值”,只有在条件为“真”的时候才会递交执行,因此被称作条件执行指令。
采用了判定指令后,原来的5条指令变成3条,避免了两条分支指令,cmp和mov可以并行执行实现50%的性能提升,消除了分支预测错误导致的大量误预测惩罚。
ARM从一开始具备完整的判定指令集,而MIPS和x86后了也都添加了条件赋值指令,IA64(EPIC)中几乎每条指令都具备条件执行功能。
第5页:
长话短说“微架构”——动态调度
为了充分利用由于分支以及长时延指令导致的流水线“气泡(停摆)”而浪费的资源,人们引入了乱序执行(OoOE)技术。
当出现需要等待某条指令的时候,程序中的指令会被“重排序(Re-Ordered)”,使得其他指令可以被执行。
对于像x86这样的ISA来说,32位模式下的寄存器只有8个(ARMv7是16个),如果程序里的变量较多,就会导致多个变量使用同一个寄存器的情况发生,这里有可能出现先读后写的伪相关现象。
微架构里解决寄存器先读后写(WAR)伪相关的办法就是寄存器重命名。
在微架构的寄存器堆里塞进比ISA寄存器更多的物理寄存器,透过索引式寄存器堆或者保留站方式,将ISA寄存器映射到物理寄存器,从而实现乱序执行。
ARMCortex-A8、IntelPentium、IntelAtom(Bonnell内核)、IBMCellPPU都属于顺序执行,它们选择顺序执行的原因主要是为了省电,因为OoOE需要大量的晶体管来实现。
随着制程的改进,OoOE的开销会逐渐淡化变得在某些场合里可行,因此像ARM从Cortex-A9、Intel从PentiumPro/Atom(Silvermont内核)都开始采用OoOE。
第6页:
长话短说“微架构”——线程级并行化
假设我们有这样的一段C代码:
intx,y;
intz;
x=100;
y=x+1;
z=5;
由于z的初始化和赋值都是相对对立的,这里也许可以拆成两条thread(线程):
thread#1:
intx,y;
x=100;
y=x+1;
和thread#2:
intz;
z=5;
如果处理器的微架构具备两种架构状态让操作系统认为有两个处理器的