imjacob的专栏

首页博文目录订阅
正 文

RISC vs CISC vs ARM

(2009-3-4 22:41)

这里介绍两种主流的计算机体系结构:
RISC(Riduced Instruction Set Computer)精简指令集计算机
CISC(Complex Instruction Set Computer)复杂指令集计算机

        所谓"体系结构",是指程序员在某CPU上进行程序设计时能够使用的处理器资源,其中最重要的是处理器所提供的指令系统和寄存器组。注意体系结构 (architecture)和组成(structure)的区别:前者是处理器的逻辑抽象,是程序员关注的部分。后者是具体实现,一般为计算机系统设计人员关注。一般来说,arachitecture,structure是不同层次的概念,但两者也有一定的联系。

        以指令系统的设计为例:相同的指令系统可以通过“硬连接”或“微程序”的方法来实现。前者通过CPU的硬件电路来实现,后者通过"微程序"来实现。如果指令集以硬连接实现,那么对于复杂指令来说,电路设计就非常困难;反之,若用微程序来实现指令集,可以实现复杂指令。现代CISC处理器一般都使用微码来实现。

        在使用微码技术的处理器中,实际存在着两套不同层次的指令:一套是面向程序员的,高层的指令;一套是面向硬件实现的,底层的微码。在指令与微码之间存在着一个“解释器”,它将指令翻译成对应的微码序列。由此可以想象,指令与微码之间的关系实际上时“子程序调用”思想的推广。

对于CISC和RISC的实现而言, 它们所侧重的复杂性不同: CISC处理器的实现复杂性更高, 而RISC编译器的复杂性更高.

微码相对于指令的特点:

        1,微码代表的都是非常简单的基本操作,而指令可能非常复杂。
        2,微码的取指操作很快:所有的微码都位于ROM中,而指令位于内存中。[note_1]
        3,微码的格式很规则,简单。因此易于译码。
        4,微码的执行速度很快,而指令相对较慢。

        从处理器架构来看,可以将使用微码技术的现代CISC的基本单元视为一个快速的RISC内核。这样问题就出来了:如果不引入“解释器”,而直接使用 RISC微码作为指令,那会怎样呢?——这正是RISC的思想。

        下面我们来看看使用微码实现的CISC指令集的优缺点:
        CISC指令集又复杂化的倾向,即向高级语言看齐,处理器厂商纷纷提供一些功能强大的复杂指令,例如:Intel针对X86处理器在MOVE基础上提供了 “成串”MOVE指令,可以将内存中数据按字节成块复制,相当于:

while (n--) *dest++ = *src++;

        这方便于复制数据结构。对于其他的复杂操作,也可以通过一条指令就实现。CISC复杂指令的寻址方式也种类繁多,操作数可以直接来自内存。但复杂指令为现代处理器技术中广泛使用的流水线技术引入了问题:在微处理器中指令的执行一般分为“预指”,“取操作数”,“运算”,“存放”等操作。对于CISC 复杂指令,他们的执行时间各不相同[note_2](有的可在4,5个时钟周期内完成,有的却需要几十个,即便对于简单指令,也会由于寻址方式的不同造成不同的执行时间)。更糟糕的是,指令长度也不一致,同一指令的长度也会因不同的寻址方式而变化。针对这些指令,如何设计流水线长度呢?若按最短指令设计流水线,当碰到复杂指令时流水线就会发生中断;若按最长指令设计流水线,执行较短指令时就会跳过某些工位,使流水线不能完全充满。

        针对上述情况,以及20-80定律(80%的情况下执行的是占指令集20%的常用指令)。多数复杂指令很少用到。当使用高级语言进行程序设计时,编译器为了兼容早期的CPU,一般不会生成特殊的复杂指令。如果舍弃这些不常用的复杂指令,就能简化CPU的设计。这正是RISC的出发点。

RISC的特点

 1,RISC指令系统较小:种类的数量较少,只提供简单指令。这些指令大多都能在4,5个时钟周期内完成。

 2,指令的操作数必须预存于寄存器中,这样取指操作的时间也统一了。

 3,指令长度,寻址方式,格式都整齐划一:这样可以充分利用流水线,基本上可实现一个时钟脉冲执行一条指令的目标。

 4,RISC的子程序调用与CISC的不同:在CISC中,程序调用、返回时需将上下文保存在堆栈中,需要内存操作。而RISC将它们存放在寄存器中,而且参数也使用 寄存器传递。(若存在嵌套的子程序调用,中间调用过程中的上下文还是要从寄存器"溅出"(spill)到堆栈中,而"叶"子程序不需要。)

 5,RISC中断可视为特殊的子程序链接:CISC中发生中断时,所有的寄存器内容都被压入堆栈,而RISC对中断进行区分对待,分为轻量级和重量级。对轻量级中断 只保存需要保存的寄存器内容;对重量级中断的处理如同常规中断。

 6,RISC都采用流水线、高速缓存、不使用微码

        当然,RISC也有它的缺点:代码密度不高,可执行文件体积较大,汇编代码可读性较差。代码密度不高是个值得关注的问题:若不使用cache,会需要更大的指令存储空间,取指时也占用更大的存储器带宽。若采用cache,又会降低cache的命中率。

RISC vs ARM

        作为RISC的新秀,ARM有它自己的特点。下文介绍ARM与RISC的比较,并归纳一下人们对RISC概念理解的误区:

ARM的独特

1,ARM可提供压缩形式的指令集:Thumb,它将ARM指令集的一个子集编码为16位指令。处理器在执行时可以切换到执行Thumb指令模式。
2,在算术指令中,可以将第二操作数在运算之前移位(如:LDREQ R0,[R1,R2,LSR #16]!)。注意:移位通过组合电路完成,而不需时钟脉冲的作用,所以不影响指令执行时间。
3,ARM支持指令的条件执行。一般处理器都只支持指令的条件转移。条件转移会使已在流水线中的后续指令作废,使流水线"断流",而条件执行避免了此情况。(当一个条件执行部分的大小超过3条指令时,还是使用条件转移指令为好)。
4,指令的执行结果是否影响程序状态寄存器中的标志位由程序员决定:在操作码后加上s(如:add - adds)就可以使运算结果改变标志位。

对RISC,CISC看法的误区

1,RISC指令都是简单指令。
        看看前面的LDREQ R0,[R1,R2,LSR #16]!指令,它的强大使一般的CISC处理器也望尘莫及。RISC的"简单"之处,在于指令集的执行时间、指令长度、指令格式整齐划一。

2,CISC的复杂指令速度慢、执行效率很低。
        现代的CISC处理器具有非常长的流水线(PIII采用了25级的流水线),对指令的执行作了充分的优化。但RISC的优势在于:不管是老的CPU,还是新的CPU,指令执行时间都是相同的,不需要在对指令执行作出优化。而同样的复杂指令,在CPU时钟频率相同的情况下,在PIII上的执行周期可能比在 386上的执行周期短很多。即CISC处理器通过对处理器的不断优化来提升指令提升速率,同样的指令,关注其执行速度时,就要考虑到采用何种CPU,而 RISC则不然。

3,RISC处理器比CISC处理器需要更多的寄存器.
        这不是一个需求问题,而是一个实现问题:RISC处理器设计比CISC简单,处理器占用较少的空间,从而腾出了空间来放置寄存器。CISC也可以由很多寄存器(68000拥有和ARM同样多的寄存器)。当然,这个观念也完全错误,就RISC的程序设计来说,它需要比较多的寄存器。

4,RISC都有流水线。
        ARM2就没有采用流水线。

        总之,RISC处理器设计的简单性使得RISC处理器在体积、功耗、散热、造价上都有优势。

[note_1] 哈佛结构,冯.诺依曼结构介绍:
        冯.诺依曼(Von Neumann)指出:程序只是一种(特殊)的数据,它可以像数据一样被处理,因此可以和数据一起被存储在同一个存储器中——这就是著名的冯.诺依曼原理。

        现代的通过计算机都是基于冯.诺依曼结构:可执行程序映象位于磁盘中,运行时,OS将它加载到内存中。

        但在用于I/O比较频繁,I/O数据量大的情况下(比如网络处理器),冯.诺依曼结构就引入了瓶颈:设想一下,当外设发起一个DMA请求并得到CPU的许可时,总线被外设所占用,CPU暂时放弃了对总线的控制,它无法访问内存来取指。早期未实现流水线的CPU采用"周期挪用"技术,利用CPU访问内存的空闲时钟周期进行DMA,解决了CPU与DMA在总线上相互排斥的问题。但随着流水线的采用,特别时在RISC处理器中,CPU在取指的同时也执行指令,内存访问已经没有空闲的时钟周期了。对于拥有较多寄存器的RISC处理器来说,数据往往就位于寄存器中,在进行DMA的时候,CPU可以执行指令。但当 CPU从内存中取指时,由于总线被外设占用,流水线被破坏。

        针对上述问题,哈佛结构也许是个解决办法:在嵌入式系统中,倾向于采用分别使用程序和数据两个存储器、两条总线的"哈佛结构"。在哈佛结构下,即使数据总线被占用,CPU也能进行取指(当CPU需要访问数据内存时,它不得不停下来)。       
        实际上,现代处理器都广泛采用了缓存技术,取指、取数据都通过cache来进行。对cache,也可分为哈佛结构和冯.诺依曼结构:是采用一个统一的 cache,还是分成数据和程序两个cache(这种情况被称为改进的哈佛结构)?在采用了流水线的CPU中,理想情况下CPU在每个时钟周期都需要取指,如果同时流水线中执行的指令需要访问内存,那两者就相互冲突了。要么让流水线暂停一拍,不取指;要么采用哈佛结构的cache,取指和访内井水不犯河水。

[note_2] 关于周期的概念:
        执行一条指令所需要的时间称为指令周期,指令周期常常用若干个时钟周期来表示。

        时钟脉冲的重复周期称为时钟周期,时钟周期是CPU的基本时间计量单位,它由计算机主频决定。

        一个CPU同外部设备和内存储器之间进行信息交换过程所需要的时间称为总线周期

 关于RISC,CISC,这里!

 这个网站介绍了ARM汇编指令,不错!http://www.cublog.cn/u/13991/showart_102442.html

评 论
3楼 52RD网友 发表于 2016-3-25 15:26 回复
不要认为一切都不可能。任何事都有可能。
2楼 52RD网友 发表于 2016-3-25 13:04 回复
没有比这个更划算的了!
1楼 52RD网友 发表于 2016-3-25 12:28 回复
“要以两倍于自己说话的时间倾听对方的话。”这是因为,人只有一张嘴,却有两个耳朵。
博 主
进入imjacob的首页
博客名称:雅克的一府
日志总数:514
评论数量:901
访问次数:1775270
建立时间:2006-11-23 20:52
导 航
公 告
Locations of visitors to this page 本博客主要用于个人学习与资料收藏。当然大家应该读了之后也能学到不少东西。其中大多数资料都是来自网络,我转载时尽可能地表明文章出处与原作者姓名,但由于很多资料经多人转载,已不清楚原作者信息与出处,所以未表明相关…
评 论
链 接

ARM+LINUX 嵌入式博客
http://blog.chinaunix.net/u1/58780/index.html

嵌入式软件
http://blog.csdn.net/embeddedsoft

诚诚恳恳做人踏踏实实编程
http://blog.sina.com.cn/u/1244756857 

和我风格相似的一个blog
http://blogger.org.cn/blog/m…