编译器技术的演进与变革

作者:亿网科技  来源:亿网科技  发布时间:2023-04-04

66.png

在曩昔的数十年里,摩尔定律一向支配着半导体职业的开展路线,跟着晶体管尺寸的不断变小单个芯片上集成的晶体管数量越来越多。

最新的 NVIDIA A100 GPU 单个芯片集成了 540 亿个晶体管,而嵌入式体系级芯片(System on Chip,SoC)中的晶体管数量,例如华为麒麟 990 集成了 103 亿个晶体管。晶体管数量的增加允许芯片规划厂商可以在单个芯片上完结更多的功用和更高的核算才能。也正是日益丰厚的功用和日渐增强的处理才能,使得软件开发人员可以不断地开发新的运用,然后驱动着整个信息技能产业不断向前开展。

在现代核算机体系中,编译器现已成为一个必不可少的基础软件工具。程序员通过高档言语对底层硬件进行编程,而编译器则负责将高档言语描绘转换为底层硬件可以履行的机器指令。编译器在将运用程序翻译到机器指令的过程中,还需求对程序进行等价改换,然后让程序可以愈加高效地在硬件上履行。

在特定硬件平台和编程言语的双重束缚条件下,运用程序的功用首要依靠于程序员编写并行代码的才能和编译器的优化才能。编译器还需求充沛弥合上层编程模型与底层硬件的巨大距离,尽可能地降低程序员的编程难度。也正因如此,编译技能的开展一直紧跟着硬件架构的演化,并且扮演着越来越重要的人物。 

1

面向经典体系结构的功用优化

从经典体系结构的角度,进步硬件功用首要有三类办法:第一类办法是将更多的精力用于开掘各种并行性;第二类办法是引入新的存储层次来缓解访存速度和存储容量之间的矛盾;第三类办法则是通过定制化的办法来进步硬件处理范畴相关运用的功用。

1.1 并行性开掘

并行性的开掘首要有三种方法,即指令级并行、数据级并行和线程级并行。根据 Flynn 分类法 ,依照指令流和数据流的不同组合方法将核算机分为以下四类:

1. 单指令流单数据流(Single Instruction, Single Data, SISD),对应串行核算机体系结构,仅能发掘指令级并行性。

2. 单指令流多数据流(Single Instruction, Multiple Data, SIMD),可用于数据并行核算,可以发掘指令级并行性和数据级并行性。

3. 多指令流单数据流(Multiple Instruction, Single Data, MISD),这类硬件的运用范围十分有限,详细实例包括暗码破译或对单一信息流进行多频率滤波。

4. 多指令流多数据流(Multiple Instruction, Multiple Data, MIMD),这是运用较为广泛的一种并行核算机体系结构,可以一起发掘指令级并行性、数据级并行性和线程级并行性。

1.1.1 指令级并行

一个处理器中心一般是指可以独立地从至少一个指令流获取和履行指令的处理单元,一般包括取指单元、译码单元、履行单元、访存单元和程序计数器和寄存器文件等逻辑单元。

指令级并行是指在单个处理器中心中,通过一起履行多条指令的方法来进步处理速度。通过巧妙地规划流水线结构,可以大幅度地进步单个处理器中心的指令级并行度。可是,受限于硬件杂乱度,处理器中正在履行指令总数与流水线的深度和个数成正比。处理器中正在运行的指令总数决定了处理器的杂乱度。

指令级并行是传统体系结构范畴中较为老练的一种并行方法,代表性的技能包括流水线(Pipeline)、多发射(Multiple Issue)、一起多线程(Simultaneous Multithreading)和超长指令字(Very Long Instruction Word)等。

其间,流水线并行是将每个功用单元通过分时复用的方法在不同的指令之间同享,是一种时刻上的并行;而多发射则是在每个时钟周期发射多条指令到多个流水线中并行履行,是一种空间上的并行;将时刻和空间维度的并行组合起来就形成了一起多线程技能和超长指令字技能。

1.1.2 数据级并行

数据级并行是一种空间维度上的并行处理方式,典型的完结方法是在硬件中集成向量运算部件,用单条向量指令一起处理多个数据,例如 Intel 的 SSE/AVX,ARM 的 NEON/SVE 等。数据级并行不仅可以充沛发掘程序中潜在的并行性,还可以精简指令序列。向量化不需求对硬件结构特别是流水线结构做很多的修正,一般只需求修正数据通路的位宽。

对于图 1.1 所示的代码,假如运行在普通的标量处理器上,编译器需求生成一个循环,通过 16 次迭代来完结整个核算任务,一次迭代完结一个元素的自增运算。假如运行在向量宽度为 4 的向量向量器上,编译器只需求生成 4 条向量加法指令即可完结核算,不需求刺进任何分支跳转指令。



1.1.3 线程级并行

线程级并行既可以在单处理器中心内完结,也可以在多个处理器中心内完结。在支撑硬件多线程技能的单处理器中,可以通过硬件多线程或许一起多线程等技能来进步资源利用率和核算效率。

可是,在规划杂乱度和功耗墙问题的共同束缚下,进步单个处理器的功用现已十分困难。一个自然的主意就是在单个芯片上集成多个处理器中心,通过发掘多个处理器中心之间的线程级并行才能来进步总体的核算才能。

在线程级并行方式中,不同履行单元的指令流相互独立,可以以同步或许异步履行的方法处理各自的数据。

首要的完结方法有:对称多处理器结构(Symmetric Multi-Processing, SMP)、分布式同享存储结构(Distributed Shared Memory, DSM)、大规模并行处理器结构(Massively Paralllel Processing,MPP)、集群(Cluster)。与线程级并行严密相关的是被 GPU 架构普遍采用的单指令多线程技能,即多个线程以锁步的方式履行相同的指令,可是每个线程处理不同的数据。

1.1.2 存储层次结构

跟着体系结构技能的飞速开展,处理器履行指令的速度远远超过了主存的拜访速度。这种日益拉大的速度差异对核算机体系结构的开展产生了巨大的影响。

为了弥合这种巨大的距离,处理器中必需要设置由不同容量和不同拜访速度的存储器构成的存储层次。存储层次可以进步程序功用的原因是确保了 CPU 大部分数据的拜访时延都比较低。跟着处理器核算速度和访存速度的差距越来越大,存储层次结构的规划显得越来越重要。

在典型的现代处理器中,每个 CPU 核有私有的 L1 Cache,一组 CPU 核有一个同享的 L2 Cache,而 L3 Cache 一般会被一切的处理器核同享。高速缓存的拜访速度往往与容量成反比。容量越大,拜访速度越低。因为程序中的时刻局部性和空间局部性,高速缓存可以作为一个有用的硬件结构将最有用的数据保持在离处理器较近的方位。

为此,高速缓存需求尽可能多地保存最近运用的数据,在容量有限的前提下尽可能地替换出最近很少运用的数据。现代体系结构中的高速缓存一般是由硬件主动管理的,可是为了极致优化功用,程序员和编译器仍需求知道存储层次的相关信息。除了硬件主动管理的高速缓存以外,现代体系结构往往还有软件自主管理的便签存储器(Scratchpad Memory)。

1.1.3 范畴定制架构

范畴定制架构(Domain-Specifific Architecture)专用性强,反而可以使得逻辑规划愈加趋于简单,在规划思路上也愈加开放,不用受到传统指令集和生态要素的制约,现已在大数据处理、数字信号处理、暗码学、高功用核算、图形学、图画处理和人工智能等范畴获得了广泛的运用。

范畴定制处理器一般会根据运用的详细特点,定制运算单元,简化操控逻辑,规划与范畴核算特征相习惯的存储结构和数据通路,尽管牺牲了通用性和灵活性,却获得了较高的功用和能效比。

特别是在第三次人工智能浪潮中,涌现出很多的面向人工智能运用的范畴专用处理器,这些人工智能处理器在功耗、功用和集成度等方面较传统的 CPU、GPU 和 FPGA 都有很大的优势。

范畴定制架构体现出范畴的专注性。以引爆第三次人工智能浪潮的深度学习算法为例,其首要特点是核算量和输入、输出(Input and Output, IO)数据量都比较大,并且并行度较高。这要求面向人工智能运用的范畴定制处理器(简称人工智能处理器)在存储结构、带宽和算力配置以及互连结构上做很多的定制化规划。

为了满意海量数据在核算单元和存储单元之间的高速传输需求,人工智能处理器不仅要具有与核算方式匹配的存储结构,还要在核算单元和存储单元之间具有高速的通讯链路。

为了满意深度学习的算力需求和核算方式需求,人工智能处理器不仅要集成大规模的并行核算单元,还要可以高效地处理深度学习算法中常见的卷积、全衔接和池化等操作。为了习惯深度学习算法的典型核算方式,人工智能处理器在结构规划时还要考虑将不同的核算单元和存储模块有机地结合在一起,尽量降低相关操作之间的数据同享开销。

可以说,深度学习算法既是核算密布的,又是访存密布的。其间核算密布的代表是卷积运算,而访存密布的代表则是全衔接运算。卷积神经网络(Convolutional Neural Network, CNN)的首要核算量也都来自卷积层。

以 GoogleNet为例,卷积核算量会占到总核算量的 90% 左右。因此,加速卷积运算是进步深度学习运用功用的中心任务。卷积层的输入是神经元和权值,通过图 1.2 所示的 N 重循环处理后,得到输出神经元。



一个卷积层包括 CO 个 C I × KH × KW 的卷积核,共计 CO × C I × KH × KW 个权值,每个卷积核对应输出神经元的一个通道。每个输出神经元涉及 C I × KH × KW 次乘累加运算,每个卷积层总的乘累加运算次数为 HO × WO × CO × C I × KH × KW。

卷积运算是一种典型的 Stencil 运算,Stencil 运算的特点是输入输出数据组织成一个多维网格,一个输出数据点的值只与接近点的输入点有关,尽管每个输出点都可以独立核算,可是运算密度较低,依靠关系杂乱。Stencil 核算方式在流体力学、元胞主动机、天气预报、粒子模拟仿真、电磁学等范畴的数值核算中都有广泛的运用。为了在范畴专用处理架构上优化这类程序的功用,需求合理地组织核算次序和数据布局,充沛开掘数据局部性和核算并行性。

作为访存密布型的代表运算,全衔接运算本质上是矩阵向量运算,可以用图 1.3 所示的两层嵌套循环来表明。全衔接运算的特点是,R 和 C 比较大,因而权值的 IO 数据量比较大;二维权值中的每个元素都只参加一次乘累加运算,权值局部性比较差,整个算法的核算密度较低。