并行处理不仅可以改善性能,而且还可以通过更好地反映系统行为和开发资源的自然分割来简化设计。
人们可以将多处理器设计定义为这样的系统:它把各项功能和任务分配给多个处理器去完成,而这些处理器彼此协调、互相沟通,以保证行为一致。多处理器系统比单处理器设计更加复杂。它要求为内务操作和协调功能进行额外的编程,调试也更为复杂。这是因为多处理器系统需要各处理器间的交互作用,而在单处理器体系结构中不存在这种处理器之间的交互作用的问题。尽管多处理器设计增加了复杂性,但多年来,它一直用于高性能计算机和工作站中,而且正跻身于日益增多的嵌入式系统应用之中。
人们之所以使用多个处理器,一条突出的理由是,它们能够比单个处理器提供更强的处理能力。在选择单处理器体系结构还是多处理器体系结构时,需要考虑的一些性能因素有:实时算法的处理量,处理外部事件所需的响应时间,所需的数学密集处理量,以及所需的并行运作的能力。多处理器体系结构可提供某种平衡负载的能力,并提供了使用定制的处理器来完成各项系统任务的机会。
现在来考虑一下如果执行时间具有很大的不定性的话,实时处
DSP体系结构通过与外设的紧密交互作用来支持快速的数据传送,从而侧重于执行连续迭代数学处理,主要是乘法-累加运算。为了实现这种连续处理功能,这些处理器常常采用复杂的存储器结构(例如多条总线和多种类型存储器的混合)和专门的指令集,其中包括定点数学运算和通过硬件加速的专用运算操作。虽然这些机制非常适合于预定的用途,但它们的性能却不如用 RISC 体系结构进行控制和响应处理的机制好。
单片系统(SOC)设计采用可编程模块这种发展趋势,使人们在明确支持嵌入式多处理器设计的处理器和芯核方面有了更多的选择。这些SoC设计所提供的性能可以升级,可以通过编程来达到超过单处理器体系结构为计算密集型应用所能提供的性能;这些SoC设计能够更好地反映许多联网系统、多媒体系统和其他嵌入式系统的自然分割,而这些系统本来就是适合多通道或会聚式应用的。对于这些类型的系统,采用多个处理器能够最好地平衡并达到工程的性能、成本、功耗、风险以及上市时间等目标。
许多嵌入式设计正在采用多处理器体系结构,并不是纯粹出于提高性能的考虑。其他考虑因素包括:既有的软件资源和开发工具,关键部件(如那些支持演进中标准的部件)的稳定性,简化工程工作,系统安全性,容错要求,满足价格、功耗、散热和电磁干扰等约束条件。多处理器体系结构可为人们提供用最合适的工程资源来完成每一项设计任务的灵活性和机遇。
人们在处理体系结构方面的经验和既有资源对目前工程的适用性方面的经验,会影响他们采用单处理器还是采用多处理器设计的抉择(参考文献1)。既有的代码或操作系统可能会决定人们选择何种处理器和如何分配工程技术人员。譬如,用不同的小组来从事前端、后端、控制和信号处理方面的工作,会影响对处理器体系结构的选择。在移动电话应用中,信号处理小组开发由 DSP 芯片来执行的无线电控制功能和语音编译码功能,应用小组则开发由微控制器来执行的人机界面功能。诸如多媒体和无线应用的标准或协议的稳定性会影响人们是将这些协议或标准作为软件来实施,以保证可编程性和灵活性,还是使用某些硬件来降低功耗和成本。
多多益善
由于软件复杂性并不是随代码长度增加而线性增加,而是比线性增加还要快,因此把软件设计得可在多个专用处理器上运行,可比在单个处理器上运行缩短开发时间,还可简化调试,并改善系统的可靠性。使用单独的处理器可以使人们更容易理解系统中被分割的各项任务之间的相互作用,并最大限度地减少由中断等待时间、处理器加载和内存使用等造成的任务之间的相互依赖性。相互作用的重点可从任务间资源共享转变为处理器之间资源的共享和专用。人们只要让整个操作系统支持系统的某些部分,而几乎不支持其他部分就可以简化性能的分配。
即使一个单处理器可以满足对性能的要求,也不可
能满足对成本、功耗、电磁干扰和散热预算等指标的要求。使用多个处理器可以降低时钟频率,以避开某些射频频率,并降低系统的电磁干扰和散热分布。如果任务分割允许把高速的突发性处理分配给某个处理器来完成,并在其不工作期间禁用该处理器,而另一个处理器则处理连续性操作,则可进一步降低系统的功耗预算。只要将安全或加密措施交给与主处理器分开的另一个处理器来实现,就可以提高系统的安全性,而且还能运行一个可以简化逆向工程的标准操作系统。尽管把多个芯核集成到一个器件中有许多好处,但人们仍然愿意选用在物理上将一个多处理器体系结构分配成若干个离散器件。例如,如果系统需要冗余或容错,就要想法使处理器故障相互隔离。分配多处理器体系结构的另一个例子是采用处理器网络模型。当将每个处理器设置在相关处理及信号的附近(如在汽车中),要求弱化处理器之间的通信、降低信号噪声并且减小系统布线重量时,这种方法是非常合适的。
某些应用不能将多个处理器轻易地分割开来,认识到这一点十分重要。如果在被分割的任务之间需要密切的通信而又想不出合适的互联方式来支持系统的吞吐量或等待时间要求,那就需要重新考虑这种分割或者放弃多处理器方
能否成功采用多处理器体系结构,取决于应用系统中固有的并行操作的数量与类型(参见附文《利用并行操作》)。许多单处理器体系结构采用了诸如流水线和超标量指令等技术,这些技术都依赖指令级的时间并行操作或空间并行操作来提高性能。SIMD(单指令多数据)和多线程技术使系统能够在数据抽象级或线程抽象级采用并行操作。软件分割是多处理系统取得成功的关键,而且这样的体系结构在人们制造它来利用系统的进程级并行操作时具有最大效益。
对称多处理(SMP)是一种同类处理器拓扑结构,在此结构中,系统能动态地将处理负载分配到一个紧密耦合的“共享一切”的多个处理器网络中。在这样的系统中,操作系统一般都了解每个处理器并管理任务的分配。这些系统保持着与高速缓存一致的子系统,并能够在处理器之间移植包括操作系统内核在内的各种进程,以平衡负载。处理器数量的增减是有限的,因为随着处理器数目的增加,系统的通信开销在总系统工作负荷中会占据更大的比例。管理多用户环境的网络服务器和事务服务器是 SMP 体系结构的共同目标。
另一种同类处理器方法是非对称地使用了多个相同的处理器。这种方法为每个处理器分配指定的具体任务,以提高系统的性能或增大其带宽。这些系统必须单独地识别每个处理器,并保持全局同步机制。当每个处理器都执行相同的任务时,或者当保持一种开发环境显得十分重要时,这种同类处理器方法非常适用;否则,异类处理器方法更为合适。
许多嵌入式应用系统得益于异类处理器拓扑结构,此类结构适用于对不同的数据进行不同操作的各种系统。异类处理器系统可以利用“同级中最好”(best-in-class)的处理器来分割并执行对它最合适的任务。一种常见的配对就是将一个管理通用系统任务的通用处理器与一个用来加速对性能起关键作用的功能或执行实时处理的专用处理器组合在一起。通用处理器(如 ARM、MIPS或 PowerPC 芯核)可以托管主操作系统,配置并启动其他处理器,管理用户和系统界面,并且执行应用软件。在任何一种多处理器设计中,处理器的数量和类型都是专用的,而且大不相同。譬如,在选择专用处理器时可以考虑选用实时控制用的微控制器、无线通信设备用的 DSP或媒体数据流传输设备用的 VLIW(甚长指令字)处理器。
处理器之间的互连方式
在多处理器系统中,处理器之间都要相互通信,相互协调。所有的多处理系统都需要用某种方法来使处理器共享数据存储器。这种方法涉及到定义专用资源和共享资源、互连接口以及协调一切的协议。在构置系统时一定要小心,不要妨碍或禁止访问这些区域,而要利用合适的仲裁或优先等级方案来平衡系统的吞吐量、延迟时间和规模大小。最终目标是按照可靠的实时预测,在合适的时间把合适的数据送到合适的地点。
作为一种极端情况,所有的处理器都访问和共享同一个物理存储器。就面积、功耗和数据传输时间而言,共享的存储器的开销较小,更适合用于紧密耦合系统。它支持比较简单的编程模型,因为每个处理器上的软件都按照同样方式访问存储器;但是其伸缩性有限,因为拥挤和争用程度会由于多个处理器同时访问存储器而增加。作为另一种极端情况,每个处理器都有自己的本地存储器。利用本地存储器的一个好处是可使数据访问速度达到最快;另一个好处是提高系统的并行处理能力,因为可以避免完全共享系统中对存储器的争用问题。它的缺点是需要重复配置资源。另外,访问数据的编程模型常常是系统专用的,不利于软件的重复利用,因为它可能需要显式重写来适应各系统之间的差异。混
合方式因设置半专用存储器以便为其他处理器提供某种访问机制,从而可协调纯共享存储器和本地存储器。许多互连接口实施方案可完成处理器之间的相互通信,但是每一种方案都只是解决不同的系统问题并在不同程度上权衡成本、灵活性、性能和可靠性等多项指标。共享存储器系统比较容易实现。如果不需要优先考虑性能的话,串行链路就是连接处理器的最便宜的方式之一。专用并行总线具有最好的性能。也可使用主机端口、SPI 链路端口、控制器区域网络(CAN)以及以太网、环形网、纵横网和网状网来实现处理器之间的通信。利用标准化的接口,如互连总线,则可简化将处理器和第三方知识产权(IP)集成到系统中的工作,并可减少开发工作量。对于嵌入式系统而言,目前尚无普遍接受的标准互连总线,但是现有多种规范支持多处理器设计,如 HyperTransport、CoreConnect、AMBA和 SuperHyway 等规范。
互连总线很容易实现,因为多个处理器共享一条总线;但是,随着总线上处理器数量的增多,每个处理器的可用带宽就会减少。有一种方法可增加总线(如 MIPS 高性能总线)所支持的处理器数量或并行操作的数量,那就是使用
在总线环境下增加处理器数量或并行操作数量的另一种策略,正如AMBA规范所定义的,是采用依赖于更简单的互连协议的多条总线或分层总线。利用分段总线或分层总线,就允许分离总线主控器,并可按照需要增加总线,从而增大系统的并行操作带宽。然而遗憾的是,使用多条总线会增加物理布线开销,总线加宽时尤是这样,这在优化整体设计区域时,是一个较大的问题。增加系统的总线数目也会增加发生串扰问题的可能性,从而增加不必要的系统成本,因为某些总线的带宽可能得不到充分利用。
把各个处理器互连起来的另一个关键要求是通信数据一致性、资源独占性和事件通知。在每个处理器上的代码执行可能要共享资源,处理来自另一个处理器的结果,并将数据传递到另一个处理器或需要来自另一个处理器的数据。通信的基本机制是存储器共享、硬件标志共享和中断共享。至关重要的是应考虑所采用的通信协议的可靠性,这样他们可以避免数据讹误、不必要的资源阻塞和死锁状态。多处理器通信的两种基本编程模型是共享存储器和消息传送共享。
人们可以非常简单地将共享存储器编程描绘成各处理器为了与其他处理器通信而从中读出数据和把数据写入的一组共享存储器区。共享存储器编程的优势在于其效率。所有的处理器都可以同时访问共享存储器,条件是各处理器从中读出数据和写入数据的存储器单元各不相同。当两个或两个以上处理器需要同时访问同一个存储器单元时就会出现争用,数据锁定机制和同步机制,如用信号量(semaphore),对于避免这种争用极为关键。实现数据锁定机制和同步机制涉及到对独占的和并行的读写操作进行管理,而这两种操作都需要进行仔细编程。
根据系统的要求,共享存储器电路可以驻留在存储器分级体系的任何一级,从而可以对成本、延迟和简易性等进行折衷设计。存储器可以在物理上共享,或者由另外一个硬件层、操作系统或软件库将它抽象成似乎是共享的,并管理数据锁定和同步。如果软件履行所有的通信和协调功能,那么这个系统的等待时间会比采用硬件初始化的系统长。
消息传送编程要求软件明确地在处理器之间发送和接收数据。与共享存储器编程模型相比,消息传送编程模型通常允许把数据分配给各处理器的颗粒更粗,对处理器之间数据分配的控制力度更强。优化的消息传送编程,其系统开销有可能比共享存储器编程小,因为它的设计可保证数据的独占性或一致性。人们可以在共享存储器系统上比较有效地实现消息传送,其方法是利用一个消息传送库来支持共享存储器系统和分布存储器系统并与这两个系统一道运行。软件并行化时采用消息传送方式的主要缺点是,程序员通常必须进行大量的修改才能创立一种有效的实现方法。
该采用何种互连机制,这取决于要解决的问题以及处理器之间的固有瓶颈问题表现在何处。对于紧耦合系统来说(在这类系统中,处理器是工作在相同数据上的),处理器可能需要通过高速总线来共享数据存储器。而对于高性能系统来说,处理器都能得益于用本地数据存储器和高速互连来传送消息。对于松散耦合的系统来说(处理器大多是独立运行的),不需要很强的交互作用,所以这些处理器都得益于使用专用数据存储器和低成本串行通信接口。
软件开发
尽管目前已有针对单处理器系统进行优化的成
熟开发工具和编程语言,但开发单处理器系统用的软件仍然具有挑战性。为多处理器系统开发嵌入式软件的工程师们,必须考虑单处理器系统中所不存在的处理器交互作用问题。引导序列和功率控制序列比较复杂。现有的软件开发工具和编程语言一般都明显偏向单处理器,这增大了为多处理器设计编写程序的难度 (见附文《多处理器编程语言》)。软件开发工具仍处于支持多处理器开发的初级阶段;最主要的工作都集中在调试程序上。大多数多处理器软件开发工作基本上是把该任务分割成各自独立的应用程序,并将它们作为独立的调试会话进行调试,采用两个或两个以上主机系统做调试。同类型系统也是如此,即使为每个处理器和所开发的软件使用的工具都一样。许多了解多个处理器的调试程序可以通过一个 JTAG 端口来按多路复用方式访问多个处理器。它们为每个处理器提供一个公共接口,但是它们可以利用处理器之间的软件同步,而你一次只能与一个处理器打交道。
对于异类系统来说,问题则更加严重,因为它们牵涉到多家供应商,而他们的成套工具是各不相同而又互不兼容的。人们必须学习每一种工具,而且协调这些工具几乎
分割点管理是多处理器调试所面临的最大挑战之一。如果人们使用各自独立的调试程序,这些调试程序会知道如何同步每个处理器的起动和停止吗?当系统识别出某个断点时,它应当停止所有的处理器吗?这些处理器和应当继续运行的处理器会发生什么情况?在识别到断点条件后,每个处理器应以多快的速度停止工作呢?对于每个断点,各个处理器的延迟时间会有多大差别呢?调试遇到的共同问题是竞态条件,此时处理器都在“争夺”共享的资源,而且因为未同步的并行访问而获得不良结果。对系统的时间行为有影响的交叉处理器调试延迟时间,使这种竞态条件更难重建。
能连贯地观察并调试处理器交互作用是一项关键的开发能力。由于多处理器系统依赖于处理器之间的通信,所以重点是确定通信方式和确保这些方式按照计划运行。目前,系统仿真是更清楚地观看多处理器系统内部和验证系统运行的重要工具。当停止整个系统并使之相关的处理器之间延迟时间过长、过于不确定,以至于无法支持细颗粒的调试时,仿真程序就尤为重要了。
展望未来
对于复杂的处理器体系结构来说,片上调试支持逻辑是必不可少的。在多处理器环境中包括兼容的调试程序块对于如何利用工具供应商的支持是十分必要,对异类处理器设计更是如此。Nexus 5001 论坛 (www.nexus5001.org) 正在努力定义并建立适用于“片上调试支持”的标准接口。
当调试系统识别出某一断点条件时,调试程序必须能够仅仅停止一个或多个处理器上的某些进程。有些进程(如电动机控制)不能停止,它们必需不停地运行。为多处理器调试提供的片上硬件辅助,开始为来自每个处理器的断点输入提供支持,并为每个处理器单独提供一个停止执行的信号。此类硬件可使每个处理器的断点信号对其他处理器一个一个地产生影响,并能缩短用于跟踪同步化和断点管理的当前等待时间。
多处理器 RTOS 支持技术及其在了解 RTOS和了解多处理器的调试工具中的集成技术将不断地走向成熟。所支持的调试功能将包括对交叉处理器 RTOS对象(包括全局对象和设备对象)内部有更大的可视度。多处理器 RTOS 甚至可以包括用来构置定制的处理器间通信管理引擎的实用程序,因为对这种通信的管理,对每一种设计实现方法都是特有的。
单片系统技术正促使多处理器设计的迅速发展,并使人们广泛探索使用这些设计的方法。人们为自己的应用选择一种优化的系统分割、互连拓扑和处理器之间的通信机制,对于设计方案的成功,既是独一无二的,又是至关重要的。因此,用于实现嵌入式多处理器设计的系统级产业标准,现在和近期都不会出台。尽管这些设计没有现行的标准方法,但人们已经在推广进程级的并行操作抽象,以探索多组适用于更复杂的高性能嵌入式的多处理器系统。