这个视频中我们会学习指令系统这一章的最后一个小节的内容。其中一些会涉及到一些我们在第五章才会学习的知识,所以在这个视频中我们只会对CISC和RISC进行一个简量的了解。
通过之前的学习,我们已经知道了在一个指令系统当中指令的格式我们应该怎么设计,另外,我们介绍了指令寻址和数据寻址两个内容,指令寻址探讨的是如何找到下一条应该执行的指令地址,而数据寻址探讨的是如何来解释这个指令里边所包含的形式地址,那通过前边的学习,我们可以感受到指令系统的设计其实很灵活的,千变万化,那这个小节中我们要学习的CISC和RISC是指令系统的两种设计方向,那所谓CISC指的是复杂指令集的计算机系统,RISC指的是精简指令集的计算机系统。
顾名思义,CISC复杂指令系统它的一个设计思想就是我们设计的这个指令系统当中会包含很多很多条指令,每一条指令都可以完成一个比较复杂的基本功能,那典型的代表就是x86架构(Intel amd),那这种复杂指令集的设计方式通常会用于笔记本,台式机或者是一些商业服务器这些地方,因为这些地方可能对功能的复杂性要求会更高一些。
再来看RISC精简指令集,他的设计思想就是只会提供一些最基本的指令,如果我们想要完成一个复杂的功能,我们可以用多条简单指令的组合来完成,那RISC的代表就是arm架构,现在大家使用的几乎所有的智能手机还有平板电脑的cpu处理器都是使用arm架构,也就使用了精简指令集的一个设计思想。
大家可以这么理解,RISC和CISC相比,RISC这种设计思想就相当于给你提供了一个c语言,但是你只能使用这个c语言里面的最基本的那些语法,什么if else 定义函数,定义变量之类的最基础的那些语法,而CISC有点类似于,他不仅给你提供了最基本的c语言,同时还给你提供了一堆你用得上,用不上的库函数,显然,要给你提供一堆复杂的指令,一堆复杂的功能,那么这种指令系统所对应的电路设计起来也会复杂的多,刚开始英特尔公司以为,指令集设计的越复杂,功能越强大会越好,cpu的效率也会越高,但是后来随着这个指令集越来越复杂,有人就发现了八十二十规律。
就是说,在大多数程序当中,可能80%的语句仅会使用到最基本的20%的指令,这点很好理解,就像大家用c语言编程,其实你会用到的语句也就是什么分支,循环,for,while,还有什么加减乘除,就是最基本的语句是你使用的频率最高的,而c语言里面包含的各种各样华丽的库函数,绝大多数你都用不到,并且即便c语言不给你提供库函数,你用c语言的基本语法自己来定义这些函数,自己来实现这些函数也是ok的,所以大家可以结合我们写程序的经验来类比着理解,对于指令的使用都是类似的原理,在复杂指令集系统当中,有很多花里胡哨的指令,我们可能使用的频率非常非常低,并且这些功能复杂的指令其实可以用多条简单的指令组合而成,但是硬件和软件不一样的是,软件的函数我们写一些代码就ok了,但是硬件的这些复杂的指令我们需要设计更复杂的硬件电路来实现,这可能会导致成本迅速上升。
现在我们站在硬件角度来举个例子,比如说,现在我们要设计一套指令集,这套指令集需要实现整数的加法,减法,乘法操作,还有矩阵的加减乘操作,那如果采用SISC的设计思想,就相当于我们会设计实现整数加减乘的指令,同时还会提供直接实现矩阵的加法,减法,乘法的指令,这是CISC的设计思路,那每一条指令都可以用一个专门的电路来完成,也就是说,对于刚才这个例子,我们需要设置三个电路来实现整数的加减乘,另外,还需要设置三个更复杂的电路来实现矩阵的加法,减法和矩阵的乘法指令,总共设计六个电路,但是有的电路也许设计起来会非常非常复杂,比如说矩阵的乘法,用电路设计也许就会比较困难,那由于这种很复杂的指令很难用硬件电路直接去完成,直接去实现,因此,随着CISC里面的指令越来越复杂,人们逐渐采用了存储程序的设计思想。
存储程序这个概念大家都知道,就是我们可以给定一串的基本的指令,把它提前存储在某个地方,比如说,对于刚才这个例子来讲,我们可以设置五个比较通用的电路,就是整数的加减乘,还有矩阵的加法,矩阵的减法,这样的五个通用的电路,这五个电路是比较好实现的,那由于矩阵的乘法更难实现一些,所以我们可以把矩阵的乘法的实现拆解为由这五个基本的指令来完成的一个操作,那这就是所谓微程序的一个概念,cpu对外提供的某些复杂的指令功能,在内部是用某些更基本的,简单的功能组合来实现了这个复杂的指令。
这是CISC的设计思路,可以提供很多功能丰富的指令,但是这些指令的设计实现也许会很复杂,对于一些特别复杂的指令没办法用硬件直接来实现的,我们就会采用微程序来实现它。
那现在对于刚才这些场景,如果我们采用RISC的设计思想,那我们就只会提供整数的加法,减法,乘法这几个指令,因为两个矩阵的加法,减法,乘法,这些操作都可以使用矩阵元素的加减乘的一个组合来实现,所以这就是RISC的设计方式,每一条指令会对应一个电路,但是由于RISC的里边只提供最基本的,最简单的那些指令,因此这些指令的电路设计也会相对简单,同时功耗也会更低,也正是因为这种精简指令集的cpu功耗更低,所以它才会被广泛的应用在我们的移动设备上,另一方面,RISC里边由于这些指令都很简单,都是一些基本的指令,因此所有的这些指令执行时间都差不多,那这个特性可以很方便的让我们实现并行技术和流水线技术,那这两个术语的具体含义,我们会在下一章当中进行学习,只要大家心里有个印象就可以。
那我们再对两种设计思路造成的一些特性差异进行一个对比,采用CISC这种设计思想,设计出来的指令系统通常是复杂且庞大的,指令的条目会很多,一般会大于200条的指令,指令功能很丰富,而如果采用RISC设计思想得到的这个指令系统通常是简单精简的,其中所包含的指令条数一般会小于100条,只会保留我们最常用的那些基本的指令,一些复杂的功能可以用简单指令的组合来完成。
那由于CISC当中指令的功能很丰富,因此,各指令的指令字长是不固定的,有可能会有很短的指令,有可能会有很长的指令,而RISC当中,由于各个指令的功能都比较单一,因此可以比较方便的设计出定长指令字结构,那之前我们说过一个指令系统当中,如果每一条指令的长度都是相等的,那么对指令的解析速度也会得到提升。
再一个方面,CISC当中有简单的指令,有复杂的指令,那不同的指令他们所需要的执行时间相差是比较大的,另外,各种指令的使用频度也相差会很大,就是之前我们提到的八十二十那个规律,而RISC当中,由于所有的指令都比较简单,所以大多数指令都可以在一个周期内就可以完成,并且所有的指令都是比较常用的,而另一个方面,对于CISC的指令系统当中,我们通常不会限制哪些指令可以访存,哪些指令不可以访存,但是在RISC当中,我们规定只有两条指令可以访存,load就是读某个储存单元,读到某一个寄存器当中,然后store就是从某一个寄存器当中往主存里边写一个数据,只能用这样的两条指令来访存,那讲到这点我们可以回顾一下之前提到过很多很多次的这个例子
这儿的第二句代码是一个乘法指令,指明了b这个数的一个存放地址是存在主存地址6这个地方,执行这条乘法指令的时候,会直接去进行一次访存操作,直接从主存当中读出0000000000000011这一串数据,然后再把b这个变量和a相乘,得到a乘以b的结果。
所以由于这个地方的乘法指令可以直接访问主存,因此,我们之前举例的这个指令系统,它一定是CISC复杂指令系统,因为刚才我们说过,如果是RISC精简指令集系统,那么我们只能用load或者store这两个指令去访问主存,而不可能说一条乘法指令也会访问主存,所以之前我们举例的这个指令系统,它一定是一个CISC的指令系统。
那也正是由于这个特性,CISC当中只需要有比较少的寄存器,而RISC当中需要有比较多的寄存器,这点从刚才的乘法指令也可以体会到。CISC里面的乘法指令,会直接把那个需要相乘的数取到某一个寄存器,然后紧接着就完成乘法操作,不会过多的占用寄存器,而对于RISC来说,无论我们要实现的是加法乘法,除法任何一种运算,一定都需要我们用一条指令先把数据从主存读入到某一个寄存器,然后再用一条指令对两个寄存器的值进行操作,因此可以看到,如果采用RISC,那么我们作为程序员也许会长期的占用很多很多个寄存器,因此,RISC这种设计方式一定要准备足够多的寄存器。
再看下一个特点,对于CISC的指令系统来说,通常我们难以用优化编译的方式生成高效的目标代码程序,而RISC,我们可以采用优化编译程序生成比较高效的代码,这个怎么理解呢,还是可以结合c语言来进行理解,之前我们说过CISC有点类似于给你提供了基础的c语言,基础语法你都可以使用,同时也给你提供了很多你用得上用不上的库函数,你当然可以通过一句代码调用一个库函数就来完成某一个复杂的功能,但是如果这个库函数实现的不是特别好,它的执行效率不是很高,那你可以修改库函数吗,是不行的,而对于RISC来说,有点类似于我们只使用这个c语言的最基础的那些语法,当我们要实现某一个复杂功能的时候,我们不可以直接调用某个库函数,但是,由于我们使用的是c语言最基本的语法,因此我们完全可以自己来优化我们的程序代码,用合理的方式优化我们的代码,就可以让我们的代码执行起来更高效,所以这地方提到的这两个特性的区别,其实原理都是和c语言类似的好,这是关于CISC和RISC目标代码的一个区别。
还有一个区别就是控制方式,CISC绝大多数情况下都会采用微程序控制,这点我们会在第五章进行进一步的探讨,这有个印象就可以,而RISC,我们可以采用组合逻辑控制,现在大家只需要知道这种控制方式效率更高,而左边这种控制方式效率会更低,只需要知道这个就可以。
最后一点,由于CISC当中各种指令的执行时间相差比较大,所以指令流水线的实现会比较困难,但是也有办法实现,就是实现起来麻烦一些,而RISC当中,由于所有的指令几乎都可以在一个周期内完成,因此可以很方便的实现指令流水线,而实现指令流水线之后,可以让cpu整体的效率得到一个质的飞跃,因此RISC当中,指令流水线都是必须实现的。
好,那这我们留下了几个空白的知识点,什么指令流水线,什么叫控制方式,什么叫微程序控制,什么叫组合逻辑控制,这些术语背后有什么含义,那这就是我们下一章需要探讨的问题。