英语原文共 41 页
异构嵌入式多核系统的软件编译技术
摘要:随着现代嵌入式系统对高性能和高能效的要求越来越高,促使多处理器片上系统(MPSoCs)采用异构多核平台。为充分利用这些平台的功能,需要新的工具来解决日益增加的软件复杂化问题,以实现高生产率。MPSoC编译器是一个工具链,能够解决应用建模、平台描述、软件并行化、软件分配和代码迭代等问题,从而有效地使用目标平台。本文以成熟的单核C编译器技术为比较基准,详细阐述了编译过程的重要组成部分。最后,从学术界和工业界的一些案例研究来说明本文讨论的概念。
1引言
-
- MPSoCs和MPSoC编译器
目前嵌入式系统设计的趋势表明,异构多处理器片上系统(MPSoC)是继续利用半导体技术所提供的高继承度的最有情景的方式,同时也符合嵌入式系统市场在性能和功率方便的限制条件。从目前的只能手机看来,很明显,它们集成了大量功能,如摄像头、数字个人助理应用、语音/数据通信和多频段无线标准。此外,与许多其他消费电子产品一样,许多非功能性参数对它们在市场上的成功都是至关重要的,例如能耗和形状系数。所有这些需求都需要出现异构的MPSOC体系结构。它们通常由各种类型的可编程内核、特殊的硬件加速器和高效的芯片网络(NOC)组成,以执行大量复杂的软件,以赶上下一轮集成浪潮。
与超级计算机和计算机集群中的高性能计算系统相比,嵌入式计算系统需要在设计过程中考虑不同的约束:
bull;实时限制:实时性能是嵌入式设备的关键,尤其是在无线和多媒体等信号处理领域。满足实时约束不仅需要硬件能够满足高性能计算的要求,还需要运行应用程序的可预测行为。
bull;能效:大多数移动设备都是电池供电的,因此能效是系统设计过程中最重要的因素之一。
bull;区域效率:如何有效地利用有限的芯片区域变得至关重要,尤其是对于必须具备可移植性的消费电子产品而言。
bull;应用领域:与通用计算不同,嵌入式产品通常针对特定的市场细分,这反过来要求针对特定应用定制系统设计的专业化。
有了这些设计标准,异构MPSoC架构被称为优于以前的单核或同构解决方案。MPSoC设计方法,也被称为电子系统级(ESL)工具,对于解决探索异构所带来的空间爆炸性设计的挑战越来越重要了。完成一个成功的MPSOC设计或一系列MPSOC产品代需要许多不同的工具,例如Texas Instruments Keystone系列。MPSOC编译器(或多核编译器)是其中的一个重要工具,也是本文的重点。
首先,什么是MPSOC编译器?目前大多数编译器都是针对单核的,针对各种核心类型(RISC、DSP、VLIW等)优化的特殊编译器的设计和实现已经得到了很好的理解和实践。现在,向MPSOC转移的趋势提高了针对这些平台的编译器的复杂性。为了有效地使用这些平台,应用程序建模、平台描述、软件并行化、软件分发和代码迭代等问题仍然是学术界和工业界尚未解决的问题。在本章中,MPSOC编译器被定义为处理给定(预先)验证的PSOC平台的这些问题的工具链。
值得一提的是,MPSOC编译器的定义与硬件-软件协同设计通信中出现的术语“软件合成”略有不同。在此背景下,软件合成强调从一个高级系统规范开始,工具执行硬件/软件分区,并自动合成软件部分,以满足规范的系统性能要求。该流也称为应用程序驱动的“自上而下”的设计流程。相比之下,MPSOC编译器主要用于基于平台的设计,半导体供应商针对特定的应用领域对MPSOC设计进行了几代人的改进。MPSoC编译器的功能与单核编译器非常接近,编译器将高级编程语言(例如C/C )转换为机器二进制代码。不同之处在于,MPSOC编译器需要在单个核心上执行额外的(和更复杂的)工作,例如软件并行化和分发,因为欠解析的MPSOC平台是按大小顺序排列的。尽管软件合成和MPSOC编译器有一些相似之处,但主要的区别在于它们存在于不同方法的上下文中,因此侧重于不同的目标。
本章其余部分的组织如下。第1.2节简要介绍了构建MPSOC编译器的挑战,将MPSOC编译器与单核编译器进行比较,然后在第2节中进行详细讨论。最后,第3节将介绍来自学术界和业界的MPSOC编译器的案例研究,探讨如何应对这些挑战。
1.2 建立MPSoC编译器的挑战
在多核时代之前,单核系统已经非常成功地为软件开发人员创建了一个舒适方便的编程环境。成功的主要原因是,顺序编程模型与人类的思维方式非常接近,而且它已经在基础工程课程中教授了几十年。此外,对单核的高级编程语言(例如,C/C )编译器进行了很好的研究,将几乎所有的硬件细节隐藏为程序员的整体工具。用户友好的图形集成开发环境(IDES)如Eclipse和调试工具如GDB也有助于单核时代的硬件和软件生态系统。
与单核相比,MPSOC体系结构的编程和编译复杂度大大提高。其原因是多方面的,最重要的原因如下。一方面,MPSOC本质上要求应用程序以并行编程模型编写,以便有效地利用硬件资源。尽管多年来致力于高性能计算,并行编程(或思维)已经被证明对程序员来说是困难的。另一方面,MPSOC体系结构的异构性要求编译过程是临时的。不同处理元素(PES)的编程模型可能不同。并行的粒度也可能有所不同。编译器工具链可以来自不同的PES供应商。所有这些都使得MPSOC编译成为一个非常复杂的过程,这很可能不再是最终用户的“整体编译器”。软件工具链既没有完全准备好处理MPSOC,也没有有效的多核调试解决方案。软件工具链还没有完全准备好处理好MPSoC系统,加上缺乏有效的多核调试解决方案。MPSOC编译器是实现MPSOC强大功能的关键工具,其构建难度很大。下面提供了基本挑战的简要列表,并在下面的第2节中进行了深入讨论。
1. 编程模型:显然,向并行编程模型的过渡从根本上影响了MPSOC编译器。
2. 平台描述:传统的单核编译器需要体系结构信息,例如后端的指令集和延迟表来执行代码生成。相反,MPSOC编译器需要另一种类型的平台描述,包括进一步的细节,例如关于PES和可用通信资源的信息。此信息用于后端之外的编译过程的多个阶段。
3. 软件并行化:虽然指令级并行(ILP)是由单核编译器开发的,但MPSOC编译器专注于更粗粒度的各种并行形式。
4. 软件分发:MPSOC编译器分发粗粒度的任务(或代码块),而单核编译器则在指令级别执行此任务。
5. 代码生成:与为一个ISA体系结构生成二进制文件相比,MPSOC编译器能够为异构PES和NOC生成最终二进制文件,这是另一个跨越式的复杂性。
2MPSoC编译器的基本元素
本节将详细探讨本章引言中提到的问题。讨论基于单核编译器的一般结构,如图1所示。本文以单核编译器技术为参考,重点讨论了MPSOC编译器任务面临的挑战。
单核编译器通常分为三个阶段:前端、中间端和后端。前端检查应用程序的词汇、语法和语义的正确性。它的输出是应用程序的抽象中间表示(IR),适用于编译器的以下阶段中的优化和代码生成。中间端(有时在概念上包含在前端)对IR执行不同的分析。这些分析使一些与目标无关的优化成为可能,这些优化主要是为了提高后验生成代码的性能。后端负责实际的代码生成,并分为多个阶段。典型的后端步骤包括代码选择、寄存器分配和指令调度。这些步骤依赖于机器,因此需要目标体系结构的模型。
为了管理复杂性,MPSOC编译器也分为多个阶段。但是,如图2所示,单核编译器的整体结构(如图1所示)将发生一些变化。通常,MPSOC编译器也分为三个阶段:软件并行化、软件分发和代码生成。在本节中,将提供有关这些阶段的更多详细信息,以帮助理解单核和MPSOC编译器之间的差异。
2.1编程模型
任何编译器的主条目都是使用给定编程模型的应用程序的表示,如图1所示。编程模型是一个桥梁,它为人们提供对底层硬件平台资源的访问。设计这样一个模型是一种微妙的艺术,在这种艺术中,为了生产效率和通常以性能为代价隐藏硬件细节。一般来说,隐藏的细节越多,编译器的工作就越难弥补性能差距。从这个意义上讲,给定的编程模型可能会减少编译器的工作,但决不会绕过使用编译器的工作。图3显示了使用不同编程语言表示不同编程模型的FIR滤波器的实现。此图显示了生产力性能权衡的示例。在一个极端,matlab实现(图3a)具有高度的简单性,并且没有底层平台的信息。C实现(图3b)提供了更多的信息,使类型和内存模型对程序员可见。另一个极端是,DSP-C实现(图3c)具有显式内存库分配(通过内存限定符x和y)和专用数据类型(accum、fract)。这一级别的编程需要更多的知识和仔细的思考,但可能会导致更好的性能。如果没有这些明确的信息,传统的C编译器将需要执行复杂的内存消歧分析,以便将数组放在单独的内存库中。
在[11]中,作者将编程模型分类为以硬件为中心、以应用程序为中心或以形式主义为中心。以硬件为中心的模型追求效率,通常需要经验丰富的程序员(例如,IntelIXP-C[51])。以应用程序为中心的模型努力提高生产率,允许快速的应用程序开发周期(例如,matlab[65]、labview[57]),以形式主义为中心的模型努力提高安全性,因为它是可验证的。嵌入式MPSOC的实用编程模型不能支付纯粹以应用程序为中心的方法带来的性能开销,并且很少为了可验证性而限制可编程性。因此,工业中使用的编程模型通常以硬件为中心,并提供一些方法来简化编程能力,这将在本节后面讨论。
与前面的分类方法不同,编程模型可以大致分为顺序模型和并行模型。后者对MPSOC编程和本章的读者特别重要,尽管它的用户被顺序编程社区所淘汰。事实上,C和C 仍然是嵌入域中的高级语言,它们具有潜在的顺序语义。程序员已经接受了几十年的连续编程教育。他们发现很难用并行的方式描述一个应用程序,当这样做时,他们引入了大量(从他们的角度来看)意想不到的错误。除此之外,还有数以百万计的顺序遗留代码,在短时间内不容易重写以利用新的并行架构。异构体系结构的并行编程模型可以进一步分类为以主机为中心和非以主机为中心。在以主机为中心的方法中,平台中的PES具有特定的角色,无论是作为主机还是计算器。在这里,执行由主机控制,并最终将计算密集型代码块卸载到专门的计算器以提高性能。相反,在非以主机为中心的方法中,代码块被分配给PES,而没有为每个PES承担任何特定的角色,并且控制流是分布式的。
而言,编译器技术在单核领域有了很大的进步。针对超标量处理器[40]、DSPS[49]、VLIW处理器[24]和单指令多数据(SIMD)体系结构[50]提出了几种优化方案。尽管如此,具有复杂内存层次结构的复杂处理器体系结构的高性能例程仍然是手工优化的,通常由处理器供应商作为库函数提供。在MPSOC时代,优化空间太大,不允许跨不同核心手工构建解决方案。MPSOC编译器必须帮助程序员优化应用程序,可能要考虑一些处理元素的优化例程。
尽管在经典编译器技术上投入了大量的精力,但是纯C编程不太可能利用未来MPSOC的处理能力。在C语言中对并行应用程序进行编码时,由于语言及其集中控制流固有的顺序语义,并行性被隐藏。检索这种并行性需要复杂的数据流和相关性分析,这些分析通常是NP完成的,有时甚至是不可确定的(见第2.3.2节)。因此,MPSOC编译器还需要处理并行编程模型,其中一些模型将在下面介绍。
2.1.1主流并行编程模型
有多种并行编程模型。现代并行编程模型是在传统的顺序语言(如C或C )之上通过编译器指令、库或语言扩展来构建的。这些模型通常按照它们支持的底层内存体系结构进行分类,不管是共享的还是分布式的。它们可以通过允许表达的平行模式进一步分类(见第2.3.3节)。如今,大多数主流并行编程模型都是行业标准,它们具有坚实的工具支持,并且不断发展以满足开发人员的需求,并利用现代多核平台的新功能。这些编程模型植根于高性能计算(HPC)社区,然而,它们在嵌入式领域获得了认可。这些模型的突出示例如下:
bull;POSIX线程(pthreads):这是一个基于库的共享内存并行编程模型。pthreads是一种低级方法,因为开发人员必须显式地创建和销毁线程、划分工作负载、将线程映射到核心并确保正确的线程同步。必须仔细设计对共享数据(关键部分)的访问,以避免数据争用和死锁。对关键部分的保护可以通过互斥(互斥)或信号量来实现。
bull;OpenMP:这是基于编译器指令的共享内存系统的行业标准并行编程模型。与pthreads相比,使用编译器指令意味着对源代码的修改最少。此外,OpenMP中的线程管理是由运行时系统完成的,这进一步简化了多核编程的挑战性任务。最初,OpenMP关注的是同构多核平台的规则循环级并行性。然而,它后来被扩展到通过其任务模型支持不规则并行,通过其加速器模型支持异构平台。加速器模型对于嵌入式领域特别重要,因为它使设计人员能够利用异构MPSOC中的所有类型的内核,包括DSP[71,74]。此外,最近的研究工作已经证实了OpenMP在嵌入式领域的适用性,因为已经证明在实时系统中使用它是可行的。
bull;OpenCL:这是一个针对异构系统的并行编程模型,也是行业标准。OpenCL遵循以主机为中心的方法,其中主机设备(如CPU)将数据和计算卸载到加速器设备(如GPU或DSP)中。在这个编程模型中,计算被描述为内核,这是执行的基本单位(例如,并行循环的一次迭代)。内核是用一种称为opencl c的语言编写的,它同时是c99标准的子集和超集。此外,OpenCL还提供了一个API,允许主机管理数据传输和目标设备上的内核执行。在嵌入式领域中,OpenCL也有
已经得到认可,并且它已经可以用于各种各样的异构嵌入式平台[41,74]。
bull;MPI:这是基于库的分布式系统并行编程模型。它依赖于消息传递原则,即支持点对点和集体形式的通信。MPI可以与其他共享内存系统的并行编程模型(如OpenMP)结合使用。虽然MPI允许利用分布
以上是毕业论文外文翻译,课题毕业论文、任务书、文献综述、开题报告、程序设计、图纸设计等资料可联系客服协助查找。