FLOPS(全部大写)是floating point operations per second的缩写,指每秒浮点运算次数,理解为计算速度,可以用来衡量硬件的性能。
FLOPs是floating point operations的缩写(s表复数),指浮点运算次数,可以用来衡量算法/模型的复杂度,表示计算量。论文中常用的还有GFLOPs和TFLOPs。
一个MFLOPS(MegaFLOPS)等于每秒一百万(=
1
0
6
10^6
106)次浮点运算。
一个GFLOPS(GigaFLOPS)等于每秒十亿(=
1
0
9
10^9
109)次浮点运算。
一个TFLOPS(TeraFLOPS)等于每秒一万亿(=
1
0
12
10^{12}
1012)次浮点运算。
一个PFLOPS(PetaFLOPS)等于每秒一千万亿(=
1
0
15
10^{15}
1015)次浮点运算。
一个EFLOPS(ExaFLOPS)等于每秒一百京(=
1
0
18
10^{18}
1018)次浮点运算。
一个ZFLOPS(ZettaFLOPS)等于每秒十万京(=
1
0
21
10^{21}
1021)次浮点运算。
GFLOPS就是Giga FLoating-point Operations Per Second,即每秒10亿次浮点运算,常作为GPU性能参数但不一定代表GPU的实际表现,因为还要考虑具体如何拆分多边形和像素、以及纹理填充,理论上该数值越高越好。1GFLOPs = 1000MFLOPs。
参数数量用Params表示,关系到模型大小,单位通常为M,由于通常参数用float32表示,所以模型大小是参数数量的4倍。
计算量用FLOPs表示,关系到算法速度,大模型的单位通常为G,小模型通常为M。
理论上的计算公式如下:
P
a
r
a
m
s
c
o
n
v
=
(
K
h
×
K
w
×
C
i
n
)
×
C
o
u
t
+
C
o
u
t
Params_{conv}=(K_h\times K_w\times C_{in})\times C_{out}+C_{out}
Paramsconv=(Kh×Kw×Cin)×Cout+Cout
F
L
O
P
s
c
o
n
v
=
[
2
×
(
K
h
×
K
w
×
C
i
n
)
×
C
o
u
t
+
C
o
u
t
]
×
H
×
W
FLOPs_{conv}=[2\times (K_h\times K_w\times C_{in})\times C_{out}+C_{out}]\times H\times W
FLOPsconv=[2×(Kh×Kw×Cin)×Cout+Cout]×H×W
注:以上公式是考虑常规卷积层操作且有bias的情况!
P
a
r
a
m
s
f
c
=
(
n
i
n
×
n
o
u
t
)
+
n
o
u
t
Params_{fc}=(n_{in}\times n_{out})+n_{out}
Paramsfc=(nin×nout)+nout
F
L
O
P
s
f
c
=
2
×
(
n
i
n
×
n
o
u
t
)
+
n
o
u
t
FLOPs_{fc}=2\times (n_{in}\times n_{out})+n_{out}
FLOPsfc=2×(nin×nout)+nout
注:以上公式是考虑常规全连接层操作且有bias的情况!
其实说到浮点计算能力,首先得区分不同精度的浮点数。半精度、单精度、双精度这些概念是在IEEE 754标准里定义的,浮点计数是利用浮动小数点的方式使用不同长度的二进制来表示一个数字,与之对应的是定点数。同样的长度下浮点数能表达的数字范围相比定点数更大,但浮点数并不能精确表达所有实数,而只能采用更加接近的不同精度来表达。单精度的浮点数采用4个字节也就是32位二进制来表达一个数字,双精度浮点数采用8个字节也就是64bits来表达,当然半精度浮点数也就是采用16bits了。因为采用不同位数的浮点数的表达精度不一样,所以造成的计算误差也不一样,对于需要处理的数字范围大而且需要精确计算的科学计算来说,就要求采用双精度浮点数,而对于常见的多媒体和图形处理计算,32位的单精度浮点计算已经足够了,对于要求精度更低的机器学习等一些应用来说,半精度16位浮点数就可以甚至8位浮点数就已经够用了。
CPU和GPU最大的不同在于内部计算单元数量的差异以及处理方式的不同,CPU内部的核心数较少而且设计上更倾向于顺序串行处理数据,GPU则因为只需要支持相对单一的数据类型和计算方式,所以计算单元较小但数量更多而且更倾向于并行处理数据。一个简单的比较是现在的Intel CPU最多也就支持24核但GPU则动不动就支持几千个核了(参考连接)。
其中最为重要的就是GPU的计算峰值,这个在我们进行边缘计算的时候,更加重要。
GPU的浮点计算能力理论峰值计算公式:
理论峰值=GPU芯片数量 × \times ×GPU Boost主频 × \times ×CUDA核心数 × \times ×单个时钟周期内能处理的浮点计算次数
只不过在GPU里单精度和双精度的浮点计算能力需要分开计算,以最新的Tesla P100为例:
双精度理论峰值 = 1 × \times × FP64 Cores × \times × GPU Boost Clock × \times × 2 = 1 × \times × 1792 × \times × 1.48GHz × \times × 2 = 5.3 TFLOPS
单精度理论峰值 = 1 × \times × FP32 cores × \times × GPU Boost Clock × \times × 2 = 1 × \times × 3584 × \times × 1.58GHz × \times × 2 = 10.6 TFLOPS
因为P100还支持在一个FP32里同时进行2次FP16的半精度浮点计算,所以半精度的理论峰值是单精度浮点数计算能力的两倍也就是达到了21.2TFLOPS。
以我的NVIDIA GeForce RTX 3080Ti为例,一个时钟周期计算次数为两次,CUDA核心数为10240,Boost主频为1.67GHz,那其单精度计算能力的峰值为:
单精度理论峰值 = 1 × \times × FP32 cores × \times × GPU Boost Clock × \times × 2 = 1 × \times × 10240 × \times × 1.67G × \times × 2 = 34201.6GFLOPS=34.2016 TFLOPS
与官方参数一致。