计算机体系结构.指令集架构
Posted 木艮氵
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了计算机体系结构.指令集架构相关的知识,希望对你有一定的参考价值。
计算机体系结构.指令集架构
微结构与ISA
微结构(Microarchitecture)对应的是底层硬件如何实现指令执行的,那么指令集架构(Instruction Set Architecture)对应的是程序员所看到的程序的模样。
具体指令是如何被处理器一步一步完成执行任务的,这交给了微结构。而到底有哪些指令可供使用、指令是什么格式、哪些通用寄存器可以用,以及这些指令在程序员看来是要如何执行的,就是ISA的范畴了。
因此程序员在某个ISA上写的程序,这个程序的每一步执行了什么操作,最终结果如何,程序员是知道的。而程序员不知道的是,每一步到底是如何被处理器完成的。
比如一个加法操作“add A,B,C”,在程序员的视角看来,就是将寄存器A和B里的数相加的结果存放在寄存器C中,之后程序员就可以把寄存器C作为A和B相加的结果来继续使用。
而在微结构的视角(假设为乱序执行),则是处理器读取到了一条指令,通过译码逻辑得知这是一条加法指令,这条指令需要寄存器A和B里的数据作为输入,因此要检查有没有正在执行的指令要写入寄存器A和B(即寻找寄存器A和B的重命名寄存器),并为其结果寄存器C进行寄存器重命名,同时在重排序缓存(ROB)中为该指令申请一个位置,然后送入指令队列(即保留站),并不断检查寄存器A和B里的数据是否可用,该指令会等待直到源数据可用,且加法运算单元空闲时,则该指令的操作码以及寄存器A和B的数据(或来自寄存器堆,或来自旁路,或来自尚未退休指令的ROB项)会送入加法运算单元,当加法运算单元完成后将结果通过总线写回到该指令对应的ROB项中,并修改该项的状态为已完成,退休(retire)逻辑每拍检查若干ROB的项,按照程序顺序完成指令的执行,即将其结果写回寄存器堆,并回收ROB项和重命名寄存器。
- 若有指令在退休时被发现有例外,则要冲刷流水线,进入例外处理。
- 若运行期间来了中断,则需要保存现场去处理中断。
- 若在此之前有一个读操作读取数据到A(或B)且未命中缓存,则该指令需要一直等待,而该指令之后的指令由于乱序可能先于这个加法操作完成执行。
- 若该指令运行在错误的分支预测路径上,则分支结果出来后该指令会被取消掉。
不同的微结构下,如何完成这条指令的执行,通常是不一样的。但程序员并不需要知道内部是如何完成的,只需要知道这条指令可以将寄存器A和B的数据相加并存入寄存器C就可以了。这就是ISA了。
ISA到底是什么
微结构负责实现每条指令是如何完成执行任务的,而ISA则可以描述指令序模型(instruction sequencing model),有两种指令序模型:
- 基于顺序的控制流(sequential control-flow)的指令序,对应经典的冯诺伊曼架构。控制流架构下有单一的程序计数器(PC),其决定了指令的获取、执行和提交的顺序。此时的指令是在PC的指挥下一条一条顺序执行的。目前大多数ISA都是基于控制流的。
- 基于数据流(data-flow execution)的指令序,对应数据流架构(Dataflow Architecture)。其在逻辑上没有PC的存在,指令的执行并不是按照程序所写明的顺序,而是按照数据依赖关系。
- 虽然学术上有不少对数据流架构的讨论,但是商业上并没有纯粹数据流架构的通用处理器,不过在数字信号处理、网络路由、数据仓库等领域则有【1】。
- 从某种意义上来说,处理器核内部的乱序执行结构也是一种数据流架构,此时指令只要满足了数据依赖,就可以送去执行了,这恰恰打乱了顺序的指令流【2】。
ISA涵盖的内容,包括但不限于以下几点:
- 指令格式:定长或变长;每个位的含义(操作码,寄存器编号,立即数等);操作数的个数;
- 寻址访存:寻址范围(地址空间);寻址模式;寻址粒度(单比特/字节/64比特等);访存方式(如load/store结构,专门的IO指令);地址对齐;
- 数据类型:8/16/32/64位整数,浮点;有/无符号;复杂数据类型(BCD码、字符串、链表);
- 寄存器:通用寄存器数量以及每个寄存器含义、宽度;整数、浮点、向量寄存器;大小端;特殊用途寄存器(如标志寄存器、架构相关的寄存器如MIPS的协处理器寄存器);
通常ISA都会包含以下三类指令:
- 运算指令:算术运算(加减乘除),逻辑运算(与或非),移位运算,向量运算等;
- 分支指令:条件分支指令,非条件分支指令(如函数调用、无条件跳转)等;
- 访存指令:load/store结构;寻址模式(寄存器寻址、基址寻址等);IO指令等;
此外还有:
- 架构相关指令:原子操作(如ll/sc);内存栅栏;缓存相关的指令;TLB相关的指令;等
- 复杂操作指令:FFT、三角函数、平方根;等
- 其他特殊用途:虚拟化指令;例外和中断(有哪些例外,是否是精确例外);核心态/用户态;访存权限检查、禁止运行位等安全方面;非对齐访存;功耗管理;延迟槽;特殊寄存器的访问;等
最后说一句,在汇编层面还有一些“伪指令”,其只对汇编器有用,不会被翻译成机器码。MIPS中的“.set“指令会影响汇编器如何将汇编翻译成机器码:“.set mips16”使汇编器进入MIPS 16模式;“.set mips3”则告诉汇编器下面的指令是MIPS IV(64位指令集,兼容32位指令)中的指令【3】。还有一些“伪指令”,只有汇编器认识,CPU不认识,在编译的时候会被汇编器翻译成 CPU 认识的汇编指令,完成相应的功能,如“li”指令通常会被翻译成“lui”和“ori”。
CISC 和 RISC
Complex Instruction Set Computer,即CISC,复杂指令集计算机。
Reduced Instruction Set Computer,即RISC,精简指令集计算机。
笼统的对比一下CISC和RISC,不完全正确,但能反应其本质上的差别:
对比 | CISC(x86) | RISC(ARM,MIPS,etc) |
---|---|---|
访存模式 | 多种寻址模式 | load/store |
指令宽度 | 变长 | 定长 |
操作数来源 | 内存或寄存器 | 寄存器 |
IO通信 | 专用的IO指令和IO地址空间 | 内存映射 |
访存对齐 | 不需要 | 需要 |
数据类型 | 多而复杂 | 少而简洁 |
寄存器堆 | 相对更小 | 相对更大 |
设计原则 | 功能多样的复杂指令集 | 功能完备的精简指令集 |
可见RISC更加简洁,因此单从架构优势上来说,普遍认为RISC更优于CISC:
- RISC的定长指令宽度以及相对规整的指令格式,简化了译码逻辑,也使得指令之间相关性的判断也更容易,比较容易实现多发射结构,此外也能节省面积、降低功耗
- RISC只有简单的数据类型,同样可以简化硬件的实现
- RISC的load/store访存模式,简化了指令相关性的判断,简化了访存操作的处理,也使得其他指令只能操作寄存器,从而可以更快地执行完成
- RISC可以用更简单的逻辑实现,比如译码结构,节省下来的面积可以使得寄存器堆更大,从而容纳更多的指令进行乱序执行,提高性能。同时更多的寄存器也可以降低编译器的复杂性,使优化工作更容易进行
- RISC的每条指令只执行很简单的操作,大多可以在一拍内完成,因此主频可以做到很高,流水线的吞吐量可以接近每拍完成1条指令(多发射则更多)
总的来说,由于RISC更加简单化,因此微结构的实现可以更加高效,指令的执行效率更容易通过流水线、多发射、乱序执行等技术来提高。对于CISC所拥有的复杂指令,比如FFT,RISC则是通过软件来实现。这种复杂指令的使用场景也非常少,因此RISC也符合“常用的做得快,少用的只要对”的原则【4】。
自从1985年以后,所有的ISA都是RISC结构。如今唯一的CISC就是x86指令集,而实际上其微结构的实现也融合了RISC的优点。
部分指令集简述
x86指令集
x86指令集在个人电脑的市场占有率上毫无疑问是王者,其创立者为Intel。可以说x86指令集是目前世界上最流行的指令集了,也被认为是现存唯一的CISC指令集。
Intel主导下的x86架构,并不一直是处理器架构做得最好的,历史上出现过的Alpha等RISC处理器其架构设计就比同时代的x86更优,1976年乔布斯和沃兹尼亚克推出的使用8位6502处理器的Apple II计算机也击败过x86架构【5】。但x86的兼容性(Compatibility)做得最好,其他如Alpha过于追求更先进的技术,甚至Alpha指令集代与代之间完全不兼容,从而淡出了市场,而x86的兼容性,使得即使在如今64位时代下,其仍能运行16位乃至8位的程序。显然如果客户每次升级处理器,都需要重写一遍程序的话,那绝对是受不了的。
而在兼容性之外,还有Intel和AMD本身的实力,足以下很多功夫在其他方面(工艺、架构)上来提高性能,以弥补架构上的差距。同时,x86架构也逐渐吸取了RISC架构的优势,在处理器内部,通过复杂的译码逻辑,将变长的复杂指令转换成定长的、简洁的微码,随后再流水执行。这样带来的缺点就是x86的译码逻辑相对于纯正的RISC来说要复杂很多,但这也许并不全是坏处。
说起指令集兼容性的重要性,有一件事十分典型,即x86从32位发展到64位时。首先是Intel与惠普联合推出了IA-64指令集,但其与32位的x86不兼容,因此难以推广。随后AMD推出了x86-64架构,是在32位的基础上增加了64位扩展,很快占据了市场。之后IA-64彻底失败,Intel也接纳了x86-64作为x86架构在64位时代的版本。
x86架构处理器的两大厂商,即Intel和AMD,只是提供处理器,并不生产整机。因此Intel和AMD都与IBM达成了合作,搭上了IBM这班飞速发展的快车。此外微软的操作系统也是长期支持x86架构。总的来看,x86处理器芯片有Intel和AMD,电脑整机有IBM,操作系统有微软,在这几大厂商的联合下,使得x86指令集架构占据了绝大部分的个人电脑市场。其他整机厂商,如1984年成立的DELL所推出的第一台计算机Turbo PC也是基于Intel 8088处理器【6】。
此外让人津津乐道的,也有AMD和Intel之间的竞争。进入20世纪后,更明确说是2006年之后,Intel几乎是压制AMD,后者也不得不在价格和性能上妥协来避免直接竞争。但在20世纪前,AMD不见得比Intel差到哪去,相反在x86最初的二十年里,AMD的实力丝毫不输于Intel,甚至更强。而AMD之所以落后则是有多方面原因,包括领导的不力、方向性的错误、Intel的不正当竞争【7】。最近几年随着锐龙架构的兴起,AMD也逐渐跟上了Intel的脚步,而Intel则饱受工艺研发的痛苦,被困在14nm工艺长达5年之久,不断滞后了先前承诺的10nm计划。
关于x86指令集的更详细内容,可以移步Intel和AMD提供的开发手册了。【8】【9】
ARM
ARM,即Advanced RISC Machine,或更早些时候的Acorn RISC Machine,是一系列RISC架构处理器。如果说x86统治了个人电脑(Personal Computer,即PC)市场,那么ARM则是统治了移动设备市场,主要是手机、平板以及嵌入式系统。这得益于RISC架构的优势,其简洁性可以很容易的实现低功耗需求,降低设计难度和散热性要求,同时具备良好的扩展性可以满足众多需求。
英国计算机公司Acorn Computers于1978年在剑桥成立,其在1980s推出了Acorn RISC Machine architecture,用于自家的PC。Acorn的第一款基于ARM的产品是一种协处理器模块,用于BBC Micro系列计算机,而BBC系列计算机也用于开发用于芯片设计的仿真软件,以及用于ARM2开发的CAD工具。
在1980s末期,Apple Computer公司和VLSI Technology公司开始和ARM合作开发新的架构。1990年Acorn将芯片设计团队独立出去,成立了Advanced RISC Machines Ltd,其母公司则为ARM Holdings,与Apple和VLSI共同开发处理器核。在1992年推出了ARM6架构,而Apple使用了基于ARM6的ARM610作为Apple Newton PDA的基础。Acorn在破产前一直在销售基于ARM的PC,而ARM Holdings则在销售芯片架构设计【10】。
ARM并不生产芯片,而是出售芯片设计,供其他厂商使用。ARM架构的授权方式主要有两类:核心级授权和架构级授权【11】:
- 前者只提供处理器核,可以和其他模块组合在一起形成可用的芯片。该授权下主要有两种级别,一种是提供门级网表(gate netlist)以及一些仿真模型和测试程序,因此无法修改核心架构,使用这种授权模式的有三星的Hummingbird和Exyno、苹果的A4、A5和A5X等。另外一种是提供HDL级的处理器核架构,此时相当于有了源代码,厂家可以自行修改,进行个性化开发,使用这种授权模式的有苹果、高通、华为、三星、博通、Xilinx等等。
- 后者则是指令集授权,可以使用ARM的ISA,内核可以自行设计,但仍需服从ARM架构。使用这种授权模式的有高通、苹果等。
MIPS、Alpha、Power、SPARC
比较知名的RISC,除了ARM外,简单介绍一下四种:【12】
- MIPS(Microprocessor without Interlocked Piped Stages Architecture)是一种十分简洁的RISC架构,其出身可谓是名门之家,由斯坦福大学的Hennessy教授领导的研究小组研制开发。由于MIPS是经典的RISC架构,且广泛用于体系结构领域的教学上,如Patterson和Hennessy的系列著作《计算机体系结构·量化研究方法》就主要以MIPS为例。如今除了ARM外,再说其RISC基本上就是MIPS了。我国的龙芯也是基于MIPS指令集,拓展了自己的指令后形成了LoongISA。
- Power是IBM开发的RISC指令集。IBM于1980年推出了全球第一台基于RISC的原型机,而1980年也是IBM在PC市场上称霸的起步时期,但IBM却选择了RISC用于高性能领域,其成功也证明了RISC比CISC在高性能上更具优势。Power架构在超算、金融等高端服务器领域表现十分成功,至今IBM仍在迭代发展Power架构。
- Alpha是一种64位的RISC指令集架构,由DEC公司设计开发,被用于DEC自己的工作站和服务器中。Alpha是一款优秀的处理器,它不仅是最早跨过GHz的企业级处理器,而且还是最早计划采用双核,甚至是多核架构的处理器。2001年,康柏收购DEC之后,逐步将其全部64位服务器系列产品转移到Intel的安腾处理器架构之上。2004年,惠普收购康柏,从此Alpha架构淡出了人们的视野。
- SPARC(Scalable Processor ARChitecture),是由Sun公司在1985年设计的指令集架构,是一种非常有代表性的高性能RISC架构。Oracle收购Sun公司之后,SPARC架构归Oracle所有。2017年9月,Oracle公司宣布正式放弃硬件业务,也包括了收购自Sun的SPARC处理器。
RISC-V
RISC-V是一个开源的指令集架构,遵循RISC的设计原则,即力求简洁性,同时保持开放性。这个开源项目于2010年起源于伯克利,随后一直发展至今。
RISC-V最大的意义在于其开源性。现有的ISA基本上都十分昂贵,如ARM的授权。此外,设计CPU也是一个很复杂、很费钱的工作,不仅需要有经验的架构设计人员,还需要不断的经历仿真、验证、流片测试,而这则是普通公司难以承受的。
RISC-V自诞生之日起就是为了解决这些问题,提供一个开源的、广泛应用的、经过验证的指令集。经过若干年的开发,RISC-V具备了完整的软件工具链,以及若干开源的处理器架构设计。2016年,RISC-V基金会成立,作为一个非盈利组织,负责维护RISC-V指令集手册和架构文档,并推动RISC-V持续发展。许多著名科技公司,如谷歌、惠普、Oracle、西部数据等,都是RISC-V基金会的创始会员,越来越多的芯片公司也开始使用或计划使用RISC-V架构。此外,许多体系结构领域的教材,如Patterson和Hennessy的系列著作《计算机体系结构·量化研究方法》,其作者本身也大力支持RISC-V架构,因此后续越来越多的教材也将以RISC-V为例。而随着物联网时代的加速到来,有一个统一的、通用的、开源的指令集架构是很有意义的。【13】
然而RISC-V的野心太大,无论是PC的王者Intel,还是移动设备的霸主ARM,都不会任由其发展下去。目前的形势下,正在兴起的物联网、AI则是RISC-V主要的发展方向【14】。
如何设计指令集
胡老师的书中提出了四点指令集设计原则【4】:
- 兼容性:指令集架构更新不能扔掉历史包袱,而设计的时候也要为未来留出空间。
- 通用性:功能上要完备,能够支持各种软件,如网络应用、科学计算、操作系统等等。
- 高效性:即简洁、规整,便于CPU的优化、编译器的实现。
- 安全性:满足安全需求。
只有这四点是不够的,或者说这四点只是针对通用处理器的指令集设计而言。
而在设计一个专用处理器的ISA的时候,常常在各方面都会面临多种选择,最重要的是清楚不同设计下的优势和劣势,根据实际的需求选择设计方案。尽管真正从零开始设计一个ISA的机会并不多,但通过这种分析可以对指令集架构有更好的了解。此外目前 RISC-V架构 的发展提供了更多接触指令集设计的机会。从2014年逐渐发展起来的深度学习处理器,也出现了许多面向深度学习处理的指令集架构。
- 运算类型:即指令集实现的功能。复杂指令越多,其单条指令能完成的功能越多,因此可以减少程序的存储空间,提高内存利用率,编译器的实现更简单,但也降低了编译优化的空间。此外复杂指令需要更复杂的硬件逻辑支持,包括译码逻辑、功能单元等。
- 语义鸿沟:即可读性。指令集越复杂,提供的指令种类越多,其可读性越好,而越精简的指令集,其许多功能需要软件实现,可读性就更差。
- 指令格式:变长的指令格式可以减少程序本身所需的存储空间,但会增加译码的复杂度;定长的指令格式常常需要更大的空间存储指令,但其译码更加简单,不仅更容易译码单条指令,而且更容易实现同时译码多条指令,支持更多指令同时发射。定长的指令常常也有更加统一的指令格式,如最高若干位通常表示操作码,这才是降低译码复杂度的主要原因。
- 寄存器堆:寄存器堆越大,实现的复杂度就越高,对芯片设计的要求也更高,需要处理访问时间、功耗、面积等各方面的问题。但越大的寄存器堆可以支持更多的指令在流水线中,提供更多的乱序空间,同时降低了编译优化的难度。此外越大的寄存器堆,就需要在指令中占据更多的位来对寄存器编码。
- 寻址模式:寻址模式越多,对编程越友好,可以增加可读性,但会加大芯片设计的难度,也会影响编译器的实现。
- 其他方面:如何处理例外和中断;是否需要/如何保证精确例外;是否需要虚拟内存;是否需要对齐访存;是否需要向量部件;需要支持哪些数据类型;使用什么存储模型;等等
参考资料
[1] WiKiPedia.Dataflow architecture[EB/OL].(2019-03-05)[2019-05-04].https://en.wikipedia.org/wiki/Dataflow_architecture
[2] Onur Mutlu.Dataflow[EB/OL].(2013-10-31)[2019-05-04].https://www.archive.ece.cmu.edu/~ece740/f13/lib/exe/fetch.php?media=onur-740-fall13-module5.2.1-dataflow-part1.pdf
[3] adaptiver.set伪指令(mips)[EB/OL].[2019-05-04].https://blog.csdn.net/adaptiver/article/details/6760220
[4] 胡伟武.计算机体系结构(第2版)[M].清华大学出版社:北京,2017:55-71.
[5] Gary Anthes.Timeline: A brief history of the x86 microprocessor[EB/OL].(2008-06-05)[2019-05-05].https://www.computerworld.com/article/2535019/timeline–a-brief-history-of-the-x86-microprocessor.html
[6] Smithsonian.PC’S Limited Microcomputer[EB/OL].[2019-05-05].https://americanhistory.si.edu/collections/search/object/nmah_1321866
[7] Graham Singer.The Rise and Fall of AMD[EB/OL].(2012-11-21)[2019-05-07].https://www.techspot.com/article/599-amd-rise-and-fall/page1.html
[8] Intel.Intel® 64 and IA-32 Architectures Software Developer Manuals[EB/OL].[2019-05-07].https://software.intel.com/en-us/articles/intel-sdm#combined
[9] AMD.Developer Guides, Manuals & ISA Documents[EB/OL].[2019-05-07].https://developer.amd.com/resources/developer-guides-manuals/
[10] David Chisnall.Understanding ARM Architectures[EB/OL].(2010-8-23)[2019-05-07].https://www.informit.com/articles/article.aspx?p=1620207
[11] WiKiPedia.ARM architecture[EB/OL].(2019-03-03)[2019-05-07].https://en.wikipedia.org/wiki/ARM_architecture#History
[12] 胡振波.ISA众生相[EB/OL].(2018-05-23)[2019-05-07].http://book.51cto.com/art/201805/574072.htm
[13] 胡振波.RISC-V架构与嵌入式开发快速入门[M].人民邮电出版社:北京,2019:19-23.
[14] 半导体行业观察.RISC-V未来将面临怎样的挑战?[EB/OL].(2019-03-10)[2019-05-07].https://www.chainnews.com/articles/711647751312.htm
以上是关于计算机体系结构.指令集架构的主要内容,如果未能解决你的问题,请参考以下文章