计算机体系结构技术杂谈(中)
例2:进阶算法
基础算法无法解决中断恢复的问题,即假如有两个写寄存器的操作,指令1,指令2,可能乱序执行时指令2的结果已经将写回了寄存器,但是指令1还未执行,此时发生中断后,从指令1重新开始执行,就会重新进行两次写入,将会发生错误。
只要保证后面指令修改机器状态时, 前面的指令都已经不会发生中断即可。很自然想到用一个额外的缓冲部件来存储即将写入寄存器内的数据,然后根据前置写入的数据是否都以完成写入来将缓存器中的内容重新写回寄存器中。这种做法也叫做 乱序执行,有序结束,所用的缓冲器通常被称为Reorder Buffer(ROB),所以基础算法的过程中要加入一个提交Commit过程。
新算法的流程如下:
1) 发射: 把操作队列的指令根据操作类型送到保留站 (如果保留站以及ROB有空), 并在 ROB 中指定一项作为临时保存该指令结果之用; 发射过程中读寄存器的值和结果状态域, 如果结果状态域指出结果寄存器已被重命名到ROB, 则读ROB 执行: 如果所需的操作数都准备好, 则执行, 否则根据结果 ROB 号侦听结果总线并接收结果总线的值
2) 写回: 把结果送到结果总线, 释放保留站; ROB根据结果总线修改相应项
3) 提交: 如果队列中第一条指令的结果已经写回且没有发生例外, 把该指令的结果从 ROB 写回到寄存器或存储器, 释放 ROB 的相应项。如果队列头的指令发生了中断或是猜测错误的转移指令, 清除操作队列以及 ROB 等。
如果某个值在提交写回寄存器时发现发生了溢出,直接清除ROB缓存即可,如果时发生中断并准备继续执行,那么从中断的指令重新执行即可。
4)示例介绍
多了一个ROB,并且结果总线和浮点寄存器的连接被断开了,内容的写回必须通过ROB进行
1)保留站(发射队列)把有序变成乱序。
2)ROB把乱序重新变成有序。
3)重命名寄存器用于保存未提交的临时结果(就是把寄存器前边加了一个空位存储ROB序号)。
这里保留站的各个位置代表的含义有变动,取消了固定的编号,同时以ROB的序号作为替代,假设依次为 Ind Qj Vj , Qk Vk,Ind表示ROB序号,即执行完需要写回哪里。Qj,Qk表示如果寄存器没有结果时,发现依赖ROB的结果,此时将ROB对应的序号填入即可。
浮点寄存器新增了一个格子,用来存储ROB序号,表明它的值依赖哪个ROB的结果
ROB缓存中三个位置分别代表 (操作类型,写入寄存器的序号,值),例如(MUL,f0,2),值为空即正在等待保留站内的指令执行完毕,如图2-20所示。
图2-20 浮点寄存器新增了一个格子,用来存储ROB序号
1) DIV发射,首先访问寄存器发现F1F2都有值,直接写入乘法保留站(如果发现有前置序号还没写入,那么就将ROB序号写入保留站中的操作数值左边的序号部分)因为其结果要写回F0,所以将写入的信息先写入ROB1,并在寄存器0前边加上ROB序号1,表明他的值依赖于ROB1的执行,如图2-21所示。
图2-21 DIV发射示例
2) MUL1发射,对F0F2首先检索寄存器,发现F2存在,但F0依赖ROB1所以将其依赖的ROB序号1写入乘法保留站中F0的序号部分,F2则直接将值写入即可序号默认写0。此时其执行结果需要写入F3,所以将其写入的内容暂时保存在ROB2中,ROB2说明其正在等待写入。同时浮点寄存器中真正要写入的F3位置标记上对应等待的ROB序号2,表示接下来的指令如果需要寄存器3的内容时,直接找ROB2就行了,如图2-22所示。
图2-22 MUL1发射
3) ADD发射,并且两个操作数都已准备好,按照上述流程继续写入即可,如图2-23所示。
图2-23 ADD发射
4) MUL2发射,F0需要等待ROB3,所以将其序号3写入乘法保留站,如图2-24所示。
图2-24 MUL2发射
5) ADD 写回,ADD执行结果写入ROB3,并且因为保留站的第一个序号就代表写回的ROB序号,所以广播时其他需要ROB3的保留站指令,都会检查并接受相关值(这里保留站4就接受了ADD的结果,因为它就在等待ROB3),结果被写入ROB3中,此时不能写回寄存器,要等待它前边的12号ROB都有了值之后才行,如图2-25所示。
图2-25 ADD写回
6) DIV写回,广播以后保留站2收到值并修改自身。ROB1接受并修改自身。此时ROB中最前边的缓存1已经有值了,开始提交,并且提交可以和写回同时执行(执行不冲突),如图2-26所示。
图2-26 DIV写回
7) 提交ROB1并修改寄存器 f0(虽然此时修改已经没啥用了),此时将指令队列中第一条指令删去。同时MUL2写回(尽管MUL1和MUL2都准备好了,但是MUL2先准备好,先来后到),如图2-27所示。
图2-27 提交ROB1并修改寄存器 f0
8) 写回MUL1,此时ROB中所有缓存都已写入,按照ROB序号的次序,依次提交三个缓存内容来修改对应的寄存器即可,如图2-28所示。
图2-28 写回MUL1
9) 依次写入三个缓存,如图2-29与图2-30所示。
图2-29 依次写入三个缓存(前)
图2-30 依次写入三个缓存(后)
2.4.1 Tomasulo算法执行示例
1. RAW、WAW、WRA相关的解决
WAR 写后读冲突(Write After Read)是指一个指令在另一个指令读取相同寄存器之后试图写入该寄存器的情况。这种情况可能会导致结果不正确或者不确定,比如有两个指令,指令1将地址a中的数据写入寄存器b,指令2将寄存器b中的内容写回地址a中,此时如果指令2提前执行了,那么就会有不确定的内容被写入地址a,导致寄存器b的内容也会错误,但是如果必须顺序执行就会发生阻塞降低执行效率
WAW 写后写冲突(Write After Write )指的是两条指令都对一个寄存器进行了写,但是有可能第一条指令的结果被其他指令依赖,但是写入以后还没读的时候就被第二条指令的结果覆盖了,这样可能造成错误结果。如果必须顺序执行,可能会专门等待依赖第一条指令的所有指令执行完才能执行第二条指令,这样效率会下降。
RAW 读后写冲突(Read After Write)是数据相关性的一种类型,指的是在流水线处理器中,当前指令要读取一个在之前指令写入的寄存器的数值的情况。这种数据相关性可能会导致问题,因为如果当前指令在前一条指令写入数据之前就需要读取这个数据,那么可能会读取到错误的数据或者数据尚未更新。为了解决 RAW 相关性,流水线处理器通常采用数据前推(Data Forwarding)或者暂停(Stalling)的方式来处理;暂停就是等一会,阻塞一会,数据前推即在数据计算完成后,将数据直接传递给需要使用它的指令,而不用等到写入寄存器后再读取。这样可以避免等待写入寄存器的延迟。
Tomasulo算法的解决方法:
1) RAW:第一条指令向R1中写入了新值,第二条指令读取了R1中的值,先写后读,写后读(RAW)相关。
①LDA R1, A ;M(A)->R1,M(A)是存储单元
②ADD R2, R1 ;(R2)+(R1)->R2
③分析:依赖总线解决, 因为总线直接将值广播到了保留站,这样就能直接完成数据前推操作,缓解RAW冲突。
2) WAR:第一条指令读取了R4中的内容,第二条指令向R4中写入了新值,先读后写,读后写(WAR)相关。
①ADD R3, R4 ;(R3)+(R4)->R3
②MUL R4, R5 ;(R4)*(R5)->R4
③分析:此时如果想要第二条指令提前执行,需要给第二条指令的R4重命名为其他的即可,这个可以通过保留站号进行操作。
3) WAW:第一条指令向R6中写入了新值,第二条指令也向R6中写入了新值,先写后写,写后写(WAW)相关
①LDA R6, B ;M(B)->R6,M(B)是存储单元
②MUL R6, R7 ;(R6)*(R7)->R6
③分析:很明显同样可以通过寄存器重命名解决,将第二条的R6重命名为其他的即可,同样可以通过保留站号操作(在进阶算法中通过缓存器解决)
2. 循环展开及流水线延迟
流水线延迟,见表2-9。
表2-9 流水线延迟
产生结果的指令
|
使用结果的指令
|
延迟 (时钟周期)
|
FP ALU op
|
Another FP ALU op
|
4
|
FP ALU op
|
Store double
|
3
|
Load double
|
FP ALU op
|
2
|
Load double
|
Store double
|
1
|
表2-9描述了不同类型指令之间的数据相关性,以及由此产生的流水线延迟。
在流水线处理器中,指令被分成不同的阶段(比如取指、译码、执行、访存、写回等),这些阶段在时钟周期内依次执行。当某条指令需要依赖另一条指令的结果时,就会产生数据相关性,可能引发流水线停顿或延迟。
这个表格中的延迟列,描述了当某条指令需要等待另一条指令的结果时,引发的额外时钟周期数。举例来说:
1)当一个浮点运算(FP ALU op)的结果被另一个浮点运算指令使用时,会有4个时钟周期的延迟,因为后续指令需要等待前面指令的结果。
2)如果一个Load double指令需要使用前面的FP ALU op 的结果,会有2个时钟周期的延迟。
这种延迟影响着流水线中指令的执行速度。当存在数据相关性时,流水线需要停顿等待相关指令的结果,这会降低处理器的性能。因此,流水线的设计需要考虑如何减少这种延迟,比如通过乱序执行、数据前瞻性加载等技术来提高处理器的效率。
循环计算Y[i] = a * X[i] + Y[i] 高斯消元法中的关键一步,见表2-10。
表2-10 循环计算Y[i] = a * X[i] + Y[i] 高斯消元法
LDCl
|
F4,0(R2)
|
;读Y[i]
|
LDC1
|
F0,0(R1)
|
;读 X[i]
|
MUL.D
|
F0, F0, F2
|
; 求 𝑎∗𝑥[𝑖]
|
ADD.D
|
FO,F0, F4
|
; 求 𝑎∗𝑋[𝑖]+𝑌[𝑖]
|
SDC1
|
F0,O(R2)
|
;保存 Y[i]
|
DADDIU
|
𝑅2,𝑅2,−8
|
|
DADDIU
|
R1,R1,−8
|
执行加法并存回
|
BNEZ
|
R1, L
|
判断𝑅1的值并跳转
|
NOP
|
|
|
对于上述计算过程,BNEZ需要两个时钟周期运行,其余的如果没有流水线延迟冲突,则各指令执行时间均为一个周期。
假设目标机器的流水线是单发射的,将次循环展开足够的次数,使得代码执行没有不必要的延迟,写出调度后的代码并计算一个元素的执行时间。
循环展开2次即可消除延迟(比如第一条指令取指后在第三条才用上,间隔了2,大于等于表中的取值并计算的延迟时间),这里消除后剩余13个指令,BNEZ消耗2个时钟周期,所以一共14个周期,单元素执行时间为 14/2,见表2-11。
表2-11 循环展开2次,可消除延迟
L:
|
L.D
|
F0, 0(R1)
|
; load X[i]
|
|
L.D
|
F6, -8(R1)
|
; load X[i-1]
|
|
MUL.D
|
F0, F0, F2
|
; a*X[i]
|
|
MUL.D
|
F6, F6, F2
|
;𝑎∗𝑥[𝑖−1]
|
|
L.D
|
F4,O(R2);
|
; load Y[i]
|
|
L.D
|
𝐹8,−8(𝑅2)
|
load Y[i-1]
|
|
ADD.D
|
F0, F0, F4
|
;𝑎∗𝑋[𝑖]+𝑌[𝑖]
|
|
ADD.D
|
F6, F6, F8
|
;𝑎∗𝑋[𝑖−1]+𝑌[𝑖−1]
|
|
DSUBUI
|
R2, R2, 16
|
|
|
DSUBUI
|
R1, R1, 16
|
|
|
S.D
|
F0, 16(R2)
|
; store Y[i]
|
|
S.D
|
F6, 8(R2)
|
; store Y[i-1]
|
|
BNEZ
|
R1, L
|
|
2.5 GCC技术
2.5.1 GCC(GNU Compiler Collection,GNU编译器套件)
GCC(GNU Compiler Collection,GNU编译器套件),是由GNU开发的编程语言编译器,见表2-12。
GNU项目始于1987年,是一个开发大量免费UNIX软件的集合(GNU的意思是 GNU’s Not UNIX,即GNU不是UNIX)。GNU编译器集合(GCC,其中包含GCC C编译器)是该项目的产品之一。
表2-12 GCC是由GNU开发的编程语言编译器
序号
|
名称
|
功能描述
|
1
|
cpp
|
C预处理器
|
2
|
gcc
|
C编译器
|
3
|
g++
|
C++编译器
|
4
|
gccbug
|
创建BUG报告的Shell脚本
|
5
|
gcov
|
覆盖测试工具,用于分析在程序的哪个位置做优化效果最佳
|
6
|
libgcc
|
GCC的运行库
|
7
|
libstdc++
|
标准C++库
|
8
|
libsupc++
|
提供支持C++语言的函数库
|
2.5.2 GCC 编译过程
1. GCC 编译过程
从hello.c到hello(或a.out)文件,必须历经hello.i、hello.s、hello.o,最后才得到 hello(或a.out)文件,分别对应着预处理、编译、汇编和链接4个步骤,整个过程如图2-31所示。
图2-31 GCC的预处理、编译、汇编和链接4个步骤
GCC预编译内容,见表2-13。
表2-13 GCC预编译内容
序号
|
步骤
|
工作内容
|
1
|
预处理(Preprocess)
|
C 编译器对各种预处理命令进行处理,包括:
(1)展开所有的头文件、
(2)宏定义的替换、
(3)解析条件编译并添加到文件中
|
2
|
编译(Compile)
|
将预处理后的文件进行词法分析、语法分析、语义分析及优化后,生成相应的.s汇编文件
|
3
|
汇编(Assemble)
|
将编译后的汇编代码翻译成机器码,生成.o目标文件
|
4
|
链接(Link)
|
通过链接器ld将目标文件和库文件链接在一起,生成可执行文件(executable file)
|
GCC预编译文件,见表2-14。
表2-14 GCC预编译文件
序号
|
命令
|
描述
|
1
|
gcc -E hello.c -o hello.i
|
预处理(预处理器 Preprocessor:cpp。-E:只对文件进行预处理,不编译汇编和链接)
|
2
|
gcc -S hello.i -o hello.s
|
编译(编译器 Compiler:gcc,g++。-S:只对文件进行编译,不汇编和链接)
|
3
|
gcc hello.s -o hello.o
|
汇编(汇编器 Assembler:as)
|
4
|
gcc hello.o -o hello
|
链接(链接器 Linker:ld)
|
2. GCC 单步完成编译
第1种命令:gcc hello.c -o hello
第2种命令:gcc -o hello hello.c
3. GCC 常用选项和参数
常用选项和参数,见表2-15。
表2-15 常用选项和参数
序号
|
命令
|
描述
|
1
|
-c
|
只编译,不链接为可执行文件,编译器将输入的.c文件编译为.o的目标文件
|
2
|
-o output_file
|
output_file 用来指定编译结束以后的输出文件名
|
3
|
-E
|
只对文件进行预处理,不编译汇编和链接
|
4
|
-S
|
只对文件进行编译,不汇编和链接
|
5
|
-g
|
产生符号调试工具(GNU 的 GDB)所必要的符号信息,要想对源代码进行调试,就必须加入这个选项。
|
g也分等级,默认是-g2,-g1是最基本的,-g3包含宏信息
|
|
|
6
|
-O
|
对程序进行优化编译,如果使用此选项的话整个源代码在编译、链接的的时候都会进行优化,这样产生的可执行文件执行效率就高
|
7
|
-ON
|
指定代码的优化等级为N,可取值为 0,1,2,3
|
8
|
-O2
|
比-O 更幅度更大的优化,生成的可执行效率 更高,但是整个编译过程会很慢
|
4. C/C++ 程序常用文件名后缀
C/C++ 程序常用文件名后缀,见表2-16。
表2-16 C/C++ 程序常用文件名后缀
序号
|
扩展名
|
说明
|
1
|
.a
|
静态库,由目标文件构成的文件库
|
2
|
.c
|
C源码,必须经过预处理
|
3
|
.C .cc .cpp
|
C++源码,必须经过预处理
|
4
|
.h
|
C/C++源码的头文件
|
5
|
.i
|
.c经过预处理得到的C源码
|
6
|
.ii
|
.C .cc .cpp经过预处理得到的C++源码
|
7
|
.s
|
汇编语言文件,是.i文件编译后得到的中间文件
|
8
|
.o
|
目标文件,是编译过程得到的中间文件
|
9
|
.so
|
共享对象库(shared object),也称动态库
|
5. 链接可分为动态链接和静态链接
C/C++ 程序常用文件名后缀,见表2-17。
表2-17 C/C++ 程序常用文件名后缀
序号
|
链接
|
描述
|
1
|
动态 链接
|
使用动态库 进行链接,生成的程序在执行的时候 需要加载 所需的动态库 才能运行。
动态链接 生成的程序小巧,但是必须依赖动态库 ,否则无法执行 。
|
2
|
静态 链接
|
使用静态库 进行链接,生成的程序包含程序运行 所需要的全部库 ,可以直接运行 ,不过体积较大 。
|
Linux 下的动态链接库实际是共享目标文件(shared
object),一般是.so文件,作用类似于 Windows 下的.dll文件。
2.6 GNU编译器(GCC)原理简介
GNU编译器(GCC, GNU Compiler Collection)是GNU工具链的关键组件,与GNU、Linux相关项目的标准编译器。它设计之初仅用来处理C语言的(也被称为GNU C编译器),紧接着扩展到C++、Objective-C/C++、Fortran、Java、Go等编程语言。
目前,GCC已经被以知道各种指令集体系结构中,成为了自由软件、专有软件的开发工具。GCC编译器可以应用多种平台:操作系统(Linux/Windows)、移动端(Android/iSO)、嵌入式系统(Arm/FPGA)等。
1. GNU编译器(GCC)的编译过程
如图2-32所示,GCC的编译工程可以分为四个步骤:
1)预处理(Pre-Processing):使用CPP对C语言源程序进行预处理生成预处理.i文件,在该过程主要对源代码文件中的文件包含(include)、预编译语句(如宏定义define等)进行分析;
2)编译(Compiling):调用CC1将预处理后的.i文件编译汇编语言.s文件,这个阶段主要是对预处理文件进行转换以生成机器语言的目标程序;
3)汇编(Assembling):GCC调用AS对汇编语言.s文件进行汇编,生成目标文件.o;
4)链接(Linking):GCC调用LD将各个模块的.o文件连接起来生成一个可执行程序文件,该过程将目标文件/库文件指派到可执行程序各自对应的位置。
图2-32 GNU编译器(GCC)的编译过程
GCC编译过程中,每个步骤都会生成不同的文件格式,C/C++在编译过程中生成的文件类型,见表2-18。
表2-18 列举了C/C++在编译过程中生成的文件类型
文件后缀
|
描述
|
.c
|
C语言源文件
|
.C/.cc/.cxx/.cpp
|
C++ 源文件
|
.h
|
C/C++ 头文件
|
.i/.ii
|
经过预处理的 C/C++
文件
|
.s/.S
|
汇编语言源文件
|
.o/.obj
|
静态库
|
.so/.dll
|
动态库
|
可以根据自己的需要控制GCC的编译过程和中间文件,以便检查、调试和优化程序。如图2-33所示,给出了C语言随着编译过程生成的文件类型。
图2-33 C语言随着编译过程生成的文件类型
2. GNU编译器(GCC)的使用方法
GCC的基本用法如下所示,使用GCC编译器需要关注两个方面:调用参数(操作方法)和文件名称(操作对象),见表2-19。
表2-19 列举了C/C++在编译过程中生成的文件类型
命令
|
作用
|
-c
|
只进行编译过程,而不链接成可执行文件,编译器只是将输入的源代码
|
-g
|
生成符号调试工具(GNU的gdb)所需要的符号信息。
|
-E
|
仅执行预处理操作,而不进行编译、汇编和链接操作
|
-S
|
仅执行编译操作,而不进行汇编、链接操作
|
-O
|
对程序进行优化编译、链接操作,提高可执行文件的执行效率
|
-o
file_name
|
设置输出文件名为file_name,注意输出文件名不能和源文件同名;如果不给出
|
GCC的外部结构遵循Unix约定,用户调用特定语言的驱动程序解释命令参数,生成完整的可执行二进制文件。
每种编程语言的编译器都是一个单独的程序,读取源代码并输出机器码;每种编程语言的前端都会解析该语言的源代码,最终生成一个抽象的语法树。
3. GNU编译器(GCC)手册使用方法
在Linux系统上,可以查看GCC的手册。在终端输入man gcc,即可打开,如图2-34所示。
图2-34 可以查看GCC的手册
手册中给出的介绍比任何资料都详细准确,但是非常的长1.6万行。快速浏览手册的快捷键与vim很相似,见表2-20。
表2-20 快速浏览手册的快捷键与vim很相似
快捷键
|
作用
|
g/G
|
跳转到文档顶/底部
|
u/d
|
向上(up)/下(down)翻动半页
|
f/b
|
向上(forward)/下(backward)翻动一页
|
/
|
在文档中搜索内容,按下/在后面输入想要查询的内容
|
n/N
|
跳转到下/上一个搜索的内容
|
q
|
退出手册
|
2.7 编译系统的结构
如图2-35所示,高级语言是输入,而汇编语言或者机器语言是输出,编译器的作用便是做一个中间转换的过程,来看看编译器是怎么把源语言翻译成机器语言的,如图2-36所示。
图2-35 编译系统结构
此部分需要借助生活中常见的英汉互译来帮助更好的理解编译器的整个结构和编译过程。
如图2-36,学过英语的都知道一些英语的语法组成,简单的英语结构可以分为主谓宾,而下面这句话可分为主谓宾补状,四个部分,而英文就是源语言,目标语言就是汉语。
翻译过程的第一步则为对源语言进行结构的拆解,确定句子中各个单词的词性(名词、动词、介词等等),此为词法分析;第二步则为进行语法分析,确定各个短语的组成(例如,In the room为介词短语,broke a window动词短语等),第三步为语义分析,确定各个短语在句子中充当什么成分,然后确定各个成分之间的关系。如图2-36所示。
图2-36 人工英汉翻译示例
图2-36是英语翻译成汉语的过程,当然实际上可能没有那么难,这只是为了举个例子,完整的翻译过程就是如此。再来看看编译器的翻译过程,如图2-37所示。
图2-37 编译器的翻译过程
编译器的翻译过程与上面的类似,词法分析——语法分析——语义分析——中间代码生成——目标代码,中间还有一些代码优化的过程(代码优化过程很重要,可以节省时间和空间)。
2.8 简单谈谈Google TPUv6
根据Google TPU第六代的数据做了一些性能数据的对比,需要注意的是TPUv6当前应该是一个用于训推一体的单Die的版本,用于训练的V6p双Die版本应该会后期再发布. 需要注意的是在国内外都开始卷大模型推理价格的时候, TPU这样的东西对于提高ROI非常有帮助。快速浏览手Google TPU版本,见表2-21。
表2-21 快速浏览手Google TPU版本
|
v4
|
v5e
|
v5p
|
v6e
|
每个pod的芯片数
|
4096
|
256
|
8960
|
256
|
chip
bf16 TFLOPS
|
275
|
197
|
459
|
926
|
HBM(GB)
|
32
|
16
|
95
|
32
|
HBM
BW(GB/s)
|
1228
|
820
|
2765
|
1640
|
每个芯片的ICI BW (Gb/s)
|
2400
|
1600
|
4800
|
3200
|
TPUv6的主要的几个优化点是MXU更大频率更高,浮点能力基本上到H100,HBM带宽和容量翻倍换了HBM3,ICI带宽也升级了。TPU互联拓扑应该和TPUv5e是一致的,如图2-38所示。
图2-38 ve5中的TPU主机框架
TPUv5e的物理结构如下,四片一块板上互联,剩余的ICI拉出到OCS光交换机上,如图2-39所示。
图2-39 TPUv5e的物理结构,四片一块板上互联,剩余的ICI拉出到OCS光交换机上
一个比较关键的点是SparseCore的升级,老的SparseCore架构,如图2-40所示。
图2-40 稀疏核硬件结构
与GB200直接C2C连接一个Grace不同的是,Google采用了在TPU内置标量核的方法,在相应的性瓦比上会比NV更有优势。TPU ve5有效缩放因子,如图2-41所示。
图2-41 TPU ve5有效缩放因子
另外Google这套东西很值得借鉴的是它在TPUv5e开始,e系列负责训推一体,Pod规模不会很大,部署更加灵活,而p系列则负责更大规模的Foundation Model训练任务.。Pathways的调度机制也维持了很好的线性加速比,例如TPUv5e可以做到50000卡基本线性加速。
2.9 NPU 是什么芯片?AI芯片都有哪些?
NPU就是CPU功能细化的产物,就像当年只有CPU一样,发现处理一些简单的重复的任务,特别像游戏这种大量作图时只能用软件算法,效率及其低下,所以发展处的加速卡,发展成为GPU,现在处理一些ai学习算法时都是用GPU软件模拟,效率低下,功耗大,所以又把这部分功能独立出来做成npu,性能更好,功耗更低,但是应用更局限,等以后又有啥专用的领域现在芯片不能满足时,还会出xxpu啥的,是这个意思吗?
人工智能的概念诞生于1956年的Dartmouth学会,麦卡锡在此次会议上正式提出人工智能的概念。人工智能经过半个多世纪的发展,目前已经应用在机器人,语音识别,图像识别,
自然语言处理,专家系统等领域。当然还有近几年超火的芯片设计领域,国内AI芯片公司也如雨后春笋般涌现。地平线,燧原,天数智芯,
寒武纪,比特大陆.....每家也都推出了自己的芯片产品。
目前市场上的对于AI芯片并无明确统一的定义,广义上所有面向人工智能(Artificial Intelligence,AI),包括Training(训练)和Inference(推理)应用的芯片都可以被称为AI芯片。脑神经图示例,如图2-42所示。
图2-42 脑神经图示例
目前市面上的
AI芯片种类太多了,各种PU(
process
unit)层出不穷,从最常见的CPU,GPU,到现在的BPU,DPU,VPU,NPU等等(当然有一些PU在严格意义上来讲,并不算AI芯片),感觉在命名上,26个英文字母已经快不够了,今天就梳理一下常见的各种PU,看看他们都是如何在各自的领域发挥作用的。
1. APU(Accelerated Processing Units)
中文名字叫加速处理器,是AMD在2011年推出的融聚未来理念产品。它第一次将处理器和独显核心做在一个晶片上,协同计算、彼此加速,使得任务可以灵活地在CPU和GPU间分配,提高效率。
当然,APU也可以指Audio
Processing Unit,专门用于处理声音数据的单元。
2. BPU(Brain Processing Unit)
BPU是自动驾驶芯片及解决方案公司研发的一款AI芯片。基于创新的人工智能专用计算架构 BPU,地平线已成功流片量产了中国首款边缘人工智能芯片——专注于智能驾驶的征程(Journey) 1 和专注于 AIoT 的
旭日(Sunrise) 1 ;2019 年,地平线又推出了中国首款车规级 AI 芯片征程2和新一代AIoT智能应用加速引擎旭日2
;2020年,地平线进一步加速AI芯片迭代,推出新一代高效能汽车智能芯片
征程 3 和全新一代 AIoT 边缘 AI 芯片平台旭日3。
3. CPU(central processing unit)
CPU的结构主要包括运算器(ALU,
Arithmetic and Logic Unit)、
控制单元(CU, Control Unit)、
寄存器(Register)、
高速缓存器(Cache)和它们之间通讯的数据、控制及状态的
总线,如图2-43所示。
图2-43 CPU的结构单元示例
4. DPU(Deep-Learning Processing Unit)
DPU的概念最早由
深鉴科技提出,成立于2016年,其产品则是基于FPGA的处理单元,拥有业界较为领先的机器学习能力,专注于神经网络剪枝、
深度压缩技术及系统级优化。2018年被Xilinx收购。
DPU也指Dataflow Processing
Unit
数据流处理器, Wave Computing 公司提出的AI架构;Data storage Processing Unit,深圳大普微的
智能固态硬盘处理器。
5. EPU(Emotion Processing Unit)
EPU这个词,也是第一次听。EPU是由Emoshape公司提出的。Emoshape是一家致力于提供可教导智能机器与人类互动技术的公司。EPU基于
微控制器(MCU)设计,在人工智能(AI)、机器人和消费电子设备中促成近乎无限的认知过程产生真正情绪反应。EPU是Ekman理论的延伸,该理论利用
情绪进化理论识别12种主要情绪。
EPU的部分主要功能包括:
1)具有高性能机器情绪意识。
2)在智能机器中创造情绪状态和合成情绪。
3)让人工智能或机器人能够体验64万亿种不同的情绪状态。
4)向其他人工智能技术传送数据,以获得一系列真实的表情和互动,并且全面了解语言和评价。
5)对话准确率高达98%。
6. FPU(Floating Processing Unit)
7. GPU(Graphics Processing Unit)
可以说这几年GPU太火爆了!国内很多AI芯片公司都是做GPU的。在5年以前,想在国内公司做GPU是很难的,但现在则有很多初创公司进入GPU领域,比如天数,沐曦,
景嘉微等。
GPU被广泛用于
嵌入式系统、移动电话、个人电脑、工作站和电子游戏解决方案当中。现代的GPU对图像和图形处理是十分高效率的,这是因为GPU被设计为很高的并行架构这样使得比通用处理器CPU在大的数据块并行处理算法上更具有优势。
从硬件设计上来讲,CPU 由专为
顺序串行处理而优化的几个核心组成。另一方面,GPU则由数以千计的更小、更高效的核心组成,这些核心专为同时处理多任务而设计。如图2-44所示。
串行运算示意图
图2-44 CPU 由专为
顺序串行处理而优化的几个核心组成
所以,GPU在图像处理等任务上,有极大的优势,结合自动驾驶等应用场景,使得GPU成为芯片行业的新宠。
8. HPU(Holographic Processing Unit)
全息处理器。
微软HoloLens是世界上首台独立的全息计算机设备,能够提供高清晰度的全息影像,其秘密在于HoloLens搭载的Holographic Processing Unit(
全息处理单元,简称HPU),这是一款定制芯片,可以处理和交互不同传感器及Intel Atom的数据串流。如图2-45所示。
图2-45 全息处理单元
9. IPU(Intelligence Processing Unit)
英国AI芯片创业公司Graphcore率先提出的概念,即
智能处理器。成立于2016年,总部位于
英国布里斯托,Graphcore的主要业务是设计用于AI应用程序的处理器,为云服务等应用提供产品支持。
Graphcore的MK2 IPU工艺为7纳米,集成了594亿个晶体管,具有1472个真正独立的处理器内核。IPU-M2000是一款即插即用的机器智能刀片式计算单元,集成了4颗
MK2
IPU,可提供1 petaFLOPS机器智能计算。如图2-46所示。
图2-46 IPU处理单元
10. JPU
JPU目前还没有明确的概念,有一称说是Job
Processing Unit,叫这个名字完全没有任何特点。
11. KPU(Knowledge Processing Unit)
嘉楠耘智的K210就是一款基于自主研发的神经网络KPU,基于RISC-V架构,目前已经应用在多个领域。如图2-47所示。
图2-47 KUP高性能处理单元
另外中科驭数也提出了KPU概念,其KPU是专为加速特定领域核心功能计算设计的一种
协处理器架构,以功能核作为基本单元,直接对应用中的
计算密集性应用进行抽象和高层综合,实现以应用为中心的架构“定制”,有效解决特定领域的海量数据处理问题。
12. MPU(Micro Processing Unit)
13. NPU(Neural-Network Processing Unit)
做NPU的公司不止一家,这里介绍一下平头哥的含光NPU。2019年9月,T-Head发布了首个
数据中心芯片-
含光800。瀚光800是一款12nm高性能人工智能推理芯片,集成了170亿个晶体管,实现了820 TOPS的峰值计算能力。在行业标准
ResNet-50测试中,实现了78563 IPS的推理性能和500 IPS/W的能效率比。如图2-48所示。
图2-48 NPU处理单元
14. PPU(Physics Processing Unit)
物理运算处理器。PPU是进行
模拟物理计算的处理器,CPU是为了达到更快的运算速度,GPU是为了达到更好的图像效果,那么PPU就是用于沟通
虚拟电子世界和普遍存在的物理真实,使画面更加真实,贴近现实。在GDC2005首次提出PPU这个概念。
15. QPU(Quantum Processing Unit)
量子处理器,利用
量子叠加性快速遍历问题的各种可能性并找到正确答案。QPU算力随
比特数n的增长呈幂指数2n增长。目前无论国内还是国外在
量子计算领域都处于探索阶段。
16. RPU
无线电处理单元?电阻处理单元?
17. SPU
服务处理部门标准产品单位流处理单元。
18. TPU(Tensor Processing Unit)
张量处理器,它是谷歌在2015年6月的I/O开发者大会上推出的计算神经网络专用芯片,为优化自身的TensorFlow机器学习框架而打造,主要用于AlphaGo系统,以及谷歌地图、
谷歌相册和谷歌翻译等应用中,进行搜索、图像、语音等模型和技术的处理。
至今,谷歌已经发布了四代TPU。
19. UPU(unified processor unit)
中微电不仅提供UPU IP,还提供芯片,其IC1是第一个基于UPU的移动系统芯片,已于去年推出工程样片,主频600MHz,是
双核-8线程。预计明年底推出IC2芯片,主频1GHz,
四核-16线程。
20. VPU(Vector
Processing Unit)
指
矢量处理器,是Intel收购的Movidius公司推出的图像处理与人工智能的专用芯片的加速计算核心。
还有视觉处理单元、视频处理单元,和GPU功能接近。
21. WPU
指英英达系统可穿戴处理,单元公司推出的可穿戴SoC产品,现在已经没有消息了。二指Web处理单元。
22. XPU
X代表未知,代表无限,任何一个尚未研发出来的处理器都可以认为是X处理器!目前的话,如果非要选一个,那么就选Xilinx-XPU吧。
23. ZPU(Zylin
Processing Unit)
Zylin是一家挪威公司,ZPU是其推出的一款32位
开源处理器。目前依然可以在github上看到它的开
源代码。
在人工智能,深度学习等概念全面融入芯片设计的时代,各家AI芯片公司顺势而起,各种概念也是层出不穷。而26个英文字母也面临着即将用尽的情况。没关系,不用慌,大不了用两个字母嘛。在未来的AI芯片浪潮中,能有多少能真正把概念做成产品推广到市场还是未知数。芯片是一个盈利周期长且投资巨大的行业,潮水退去后,就知道到底哪些公司在裸泳。
AI芯片设计在国内处于百花齐放的状态,相比国外,不算落后,这是希望看到的,也希望AI芯片能为带来更具想象力的应用场景。