编译器技术的演进与变革

220658d776bb9e39a378b6c5a89aa868.jpeg

在过去的数十年里,摩尔定律一直支配着半导体行业的发展路线,随着晶体管尺寸的不断变小单个芯片上集成的晶体管数量越来越多。

最新的 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 条向量加法指令即可完成计算,不需要插入任何分支跳转指令。

8078cf45b56b05a44e0ed0ec5511d4a9.png

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 重循环处理后,得到输出神经元。

0aed8bfd30b96699790579525d92b270.png

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

卷积运算是一种典型的 Stencil 运算,Stencil 运算的特点是输入输出数据组织成一个多维网格,一个输出数据点的值只与临近点的输入点有关,虽然每个输出点都可以独立计算,但是运算密度较低,依赖关系复杂。Stencil 计算模式在流体力学、元胞自动机、天气预报、粒子模拟仿真、电磁学等领域的数值计算中都有广泛的应用。为了在领域专用处理架构上优化这类程序的性能,需要合理地组织计算次序和数据布局,充分发掘数据局部性和计算并行性。

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

26748051dd4f42ed9fab3edb0f48d27b.png

2

编译器面临的挑战

前面从经典体系结构的角度介绍提升硬件性能的三类主要方法,即发掘并行性、优化存储层次和领

  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值