Introduction to AI Infra, from HPC Perspective
From HPC To AI Infra 并行计算与并行编程
对于经典的冯诺依曼架构处理器,计算机程序都是由处理器执行的一连串指令流,每个任务通常分为取指、译码、执行、访存、写回五步骤,其执行指令的基本单位是时钟周期(clock cycle).IPC性能(instructions per cycle),即指的是每个时钟周期执行指令的条数.
对于单个处理器执行若干部分,通常是串行计算的.
对于ICP > 1的处理器,它可以在同一个时钟周期内执行两个指令,此时我们叫做它能够实现超标量性能.在实际中,处理器通常配备多个计算单元,实现并行计算,比如多核处理器,高性能网络等.
正如在Programming Massively Parallel Processors中所描述的,为了尽最大可能利用并行计算,我们需要考虑两个指标,Latency和Throughput,也即延迟和吞吐.前者指一条指令执行所需时间,后者指单位时间内进行的计算量(吞吐量).增大并行化以及并行度,则是并行计算优化的重要方向.
对于代码而言,如果之间并无依赖关系,则说明这两段代码的计算是可并行的;反之,如果下一行代码需要使用到上面代码的计算结果,则说明代码间有依赖关系,并不独立.
如果对于并行的程序间,发生同时访问同一资源等情况,会导致竞争的发生,二者会”抢资源”.为了解决这一情况,需要加互斥或者锁,以确保顺序可知.
相似的,有时候因为不知道每个并行部分的计算进展如何,而下一步需要利用这些整体的结果.为了确保所有并行部分都已执行完毕,需要增加同步部分,比如对计算结果取最大值,我们首先需要确保所有部分都已计算完毕,此时进行同步后再来进行比较取最大值.
在当今世界中,气候模拟、物理模拟、生物模拟、深度学习与人工智能等领域,大部分重要计算都是可并行的.并且由于规模影响,并行计算有着不可替代的优势.最简单的例子就是矩阵乘法,GEMM,通常需要使用并行来计算,详情可参考Chapter 15, Advanced Optimizations for Matrix Multiplication, Programming Massively Parallel Processors.
因此,如何分配任务,如何拆分任务到不同并行单元以充分利用并行单元算力,提高并行度,成为重要的研究方向.通常的切分方式有预切分(Domain Decomposition), 功能切分(Functional Decomposition)
从体系结构的角度看并行计算机,硬件上可以分为四类计算结构种类: - SISD,实际上是串行结构,一条指令,一条数据,现已无相关实际硬件结构 - SIMD,一条指令,多条数据读取,对于向量计算友好,现实中NPU是一个例子 - MISD,一个数据,多条指令,读取一个数据后利用这一数据进行多条指令计算,现在很少有实例 - MIMD,多指令,多数据,当代最广泛应用的结构,现在CPU、GPU几乎都是这一结构
对于并行程序而言,通信有以下四种模式: - broadcast广播,一个程序发送内容到其他程序去做 - scatter切割,一个程序的任务切割并分发给其他程序去做,每个程序负责一部分 - gather聚合,不同程序的计算结构汇合到某一个程序中去 - reduction归约,通常是对指定的二元运算求结果的计算,每个部分的计算结果都是由上一结果和自身元素的二元运算结果
而NVIDIA对于并行计算的视角,则是使用SIMT模型&CUDA生态,这一部分详情参考书籍Programming Massively Parallel Processors.实际上对于程序员而言,更多时候是注意到一个数据块的计算,也就是Tile模型,将计算分割为若干tile,这是一种更友好程序员思考的模型.






