天天看点

《计算机系统:系统架构与操作系统的高度集成》——2.11 影响处理器设计的问题

本节书摘来自华章计算机《计算机系统:系统架构与操作系统的高度集成》一书中的第2章,第2.11节,作者:(美)拉姆阿堪德兰(ramachandran, u.)(美)莱希(leahy, w. d.)著, 更多章节内容可以访问云栖社区“华章计算机”公众号查看。

2.11.1 指令集

在本章中,我们一直把注意力集中在指令集设计上面。我们对指令集首先关心的是能够将高级语言结构编译为有效的机器码。这种关心在某些角度上是正确且有意义的。然而,这并不是intel或amd这类公司的体系结构工程师通宵达旦所挂念的事情。事实上,在20世纪80年代和90年代出现了许多isa,虽然它们的优雅程度不一,但都是由我们前面讨论的问题驱动的。从优雅和性能的角度来说,digital equipment corporation(dec)的alpha体系结构是最好的体系结构之一。dec alpha的体系结构工程师对编译器生成代码的直观性和有效性以及isa的设计如何能有效实现进行了大量的思考。随着dec公司这个20世纪80年代和90年代的微型计算机先锋的死去,alpha体系结构也走到了尽头。

20世纪80年代出现了复杂指令集计算机(complex instruction set computers, cisc)和精简指令集计算机(reduced instruction set computer, risc)之间的争论。使用cisc型isa,编译器作者的任务就会变得更复杂,因为将高级语言结构编译为机器码有太多的选择。除此之外,isa的复杂性对于硬件的有效实现也是个巨大的挑战。对于编译器作者来说,有选择大体上是好事,但如果程序员不懂得性能通常需要优先考虑的话,那这些选择就有问题了。随着编译器技术的日渐成熟,有人认为risc型的isa比cisc型的isa更加易于编译器作者使用,同时也能更有效地实现。

我们都知道,intel的x86是一个经得住时间考验的isa,它是一个cisc型的isa。目前,x86还是占主导地位的isa。与此同时,许多更优雅的指令集,如dec alpha,已经消失了。原因在于决定指令集成败的其他因素有很多(市场压力是主要因素)。性能因素当然是很重要的考量,但真正好的指令集,如alpha,它们相对于x86的性能优势还没有大到让它们成为主导者。另外,尽管x86指令集的硬件实现很有挑战性,但intel和amd聪明的体系结构工程师已经做出了有效的实现,由于它在时钟频率上很占优,因此一个“好的”指令集的性能优势并不大,至少没有足够大来取代已经占据市场的指令集如x86。

究其根本,一个指令集的成败很大依赖于市场对它的接纳程度。今天计算机软件支持着从商业到娱乐的一切。因此,主要的软件商(如microsoft、google、ibm和apple)对指令集的接纳程度成了决定指令集成败的关键因素。另一个同等重要的因素是计算机制造商(如dell、hp、apple和ibm)对采用这种指令集的处理器的接纳程度。除了传统的市场(笔记本、桌面电脑和服务器),嵌入式系统(例如游戏机、手机、掌上电脑和汽车)也成了计算机领域中的重要部分。很难精确地描述为什么某个指令被或不被这些软件巨头、计算机制造商和嵌入式系统开发者接纳。尽管我们趋向于认为这是由指令集的优雅程度决定的,但是从计算机的历史上看,并非如此。这些决定通常是依据语用学pragmatic做出的,即是否有针对该isa的好的编译器可用(尤其是c语言),是否支持遗留代码,等等。

2.11.2 应用程序对指令集设计的影响

应用程序在过去影响着指令集的设计,今后还会继续影响。在20世纪70年代,甚至到20世纪80年代早期,计算机主要用于处理数字的科学和工程应用程序。这些应用非常依赖于浮点算术。高端计算机(如ibm 370系列机和cray)在指令集中包含了这些指令,而当时所谓的小型机(如dec pdp 11系列)则没有包含这些指令。曾经有成功的公司(如floating point systems公司)制作附加的处理器用于为小型机提供浮点运算加速。如今,浮点指令已经是任何通用处理器的一部分了。用于嵌入式应用如手机和掌上电脑的处理器(如strongarm、arm)可能没有这些指令,它们通过数学库使用整数指令来实现浮点运算。

另一个应用程序影响指令集设计的例子是intel的mmx指令。有的应用程序专门处理音频、视频、图像这样的流数据,即像电影和音乐这样的连续数据。这些数据在内存中通常表现为数组。mmx指令由intel公司于1997年在奔腾系列处理器中首先引入,目标是让cpu能够高效处理流数据。这套指令背后是很简单的直觉。正如流数据这个名称所暗示的,音频、视频和图像应用需要在两个或多个流相应的数据上进行相同的操作(比如加法)。所以,应该有指令去模仿这种行为。mmx指令最初是在奔腾处理器中引入的,奔腾的后继型号也继承了它。一共有57条指令,分成算术、逻辑、比较、转换、移位和数据传输,每个指令都有两个操作数(不是标量,而是许多元素构成的向量)。比如,一个加指令会把两个向量中对应位置的元素相加。

一个更近的例子来自于游戏产业界。交互式的游戏已经变得非常复杂。实时游戏控制端的图像和动画处理需求已经超出了通用处理器的处理能力。当然,你下次假期旅行时不可能拖着一台超级计算机去玩游戏!于是出现了图像处理单元(gpu),这是专用的外接处理器,用于完成游戏控制端所需的算术运算。基本上,gpu包含了许多功能单元(实现图像渲染应用所需的基本操作)来并行处理流数据。最近sony、ibm和toshiba的合作项目公开了cell处理器,进一步发展了gpu的概念。cell处理器在一块芯片上集成了几个处理元素,每个都能被编程以完成特定的任务。cell处理器体系结构已经应用于playstation(ps3)中。

2.11.3 其他驱动处理器设计的问题

指令集设计只是现代处理器设计中的问题之一,甚至不是最引人关注的问题。这里列出了更多重要的问题,其中的一些将在后面的章节中详细阐述。

1)操作系统 我们提到过,操作系统在处理器设计中扮演着重要的角色。它的一个表现是,系统给程序员造成一种假象,让内存空间看起来比实际内存容量大得多。另一个表现是处理器对中断等外部事件的响应能力。在后面的章节我们将看到,为了满足操作系统的需求,处理器需要包含一些新的指令,以及一些从指令集层面看不出来的体系结构的新机制。

2)对现代语言的支持 大多数现代语言如java、c++和c#都向程序员提供了动态增长和缩小程序的能力。这称为动态内存分配,这个特性从应用开发程序员和操作系统资源管理的角度来说都非常有力。当数据尺寸缩小的时候恢复内存,即垃圾回收机制,是资源管理的关键。处理器体系结构中自动回收垃圾的机制是当今处理器设计中的一个热点。

3)存储系统 如你所知,处理器的速度在过去十年中按照接近指数的规律增长着。例如,1986年,一台sun 3/50拥有一颗0.5 mhz的处理器;2007年,笔记本和桌面电脑拥有超过2 ghz的处理器。内存的密度也按指数增长着,但内存的速度却跟不上处理器的增长速度。处理器和内存速度的这种不一致被称为内存墙。在处理器设计中,使用聪明的技术来越过这道内存墙是最重要的问题之一。例如,设计高速缓存并将它集成到处理器中就是这类技术。我们在后面的存储器层次章节中会包括这些内容。

4)并行性 随着芯片密度的提高,单块硅片上常常可以集成数以百万计的晶体管,这使得在单个处理器上能够放置更多的功能单元。实际上,芯片的密度已经达到可以在同一块硅片上放置多个处理器的高度。这种称为多核和众核的体系结构,带来了一系列全新的处理器设计的问题。其中的一些问题,例如并行编程和内存一致性问题,是从传统的多处理器机器(含有多个处理器的计算机)上搬过来的,我们在后面中会讨论它们。

5)调试 程序变得复杂了。类似于web服务器这样的应用,除了并行和拥有极大的内存印迹之外,可能还包含接触网络和数据库的组件。写这样的程序自然很不简单。现代处理器设计的一个重点就是有效地支持调试,尤其是并行程序。

6)虚拟化 随着应用程序复杂性的增加,它们的需求也越来越复杂了。例如,一个应用可能用到某些服务,而这些服务只存在于某些特定的操作系统中。如果你要同时运行多个程序,而每个程序又有各自的需求,那么就需要支持同时存在多个应用执行环境。由于某些原因,你可能会在笔记本上装双系统。如果能够让多个操作系统共存,且不需要来回切换的话就好了。虚拟化是这样一个系统概念,在同一个计算机系统上支持多个不同的运行环境。体系机构工程师们开始注意如何在现代处理器设计中有效地支持这个概念。

7)容错性 随着硬件体系结构变得更加复杂,有了多核与众核以及庞大的层次存储系统之后,部件出错的可能性增加了。体系结构工程师们现在更加注意设计让处理器对程序员隐藏这些失败的技术。

8)安全性 在这个时代,计算机的安全是个大问题。当提到保护计算机安全的时候,通常会想到网络的攻击。事实证明即使在计算机内部(在内存系统和cpu之间)也会出现安全问题。体系结构工程师们试图在处理器和内存的通信中采用加密技术来缓解这类问题。

继续阅读