MNIST在CPU、FPGA、ARM上的运行对比
CPU与FPGA对比
CPU
CPU是通用处理器,串行的执行指令。
CPU、GPU 都属于冯·诺依曼结构,指令译码执行、共享内存。冯氏结构中,由于执行单元(如 CPU 核)可能执行任意指令,就需要有指令存储器、译码器、各种指令的运算器、分支跳转处理逻辑。由于指令流的控制逻辑复杂,不可能有太多条独立的指令流,因此 GPU 使用 SIMD(单指令流多数据流)来让多个执行单元以同样的步调处理不同的数据,CPU 也支持 SIMD 指令。
FPGA
FPGA是硬件可重构体系,可以并行的进行运算,所以有强大的计算量,而且灵活性非常高。
FPGA 每个逻辑单元的功能在重编程(烧写)时就已经确定,不需要指令。FPGA 非常更适合做需要低延迟的流式处理,而像GPU 适合做大批量同构数据的处理。
FPGA在某些方面有优势在某些方面也有劣势,FPGA适合并行、低延迟计算,但CPU就适合处理数据信息。缺少指令同时也是 FPGA 的优势和软肋。每做一点不同的事情,就要占用一定的 FPGA 逻辑资源。如果要做的事情复杂、重复性不强,就会占用大量的逻辑资源,其中的大部分处于闲置状态。这时就不如用冯·诺依曼结构的处理器。因此FPGA 和 CPU 协同工作,局部性和重复性强的归 FPGA,复杂的归 CPU。
下面我们来对MNIST手写体识别在CPU和FPGA运行速度(只看推理速度)做个对比。
CPU上进行MNIST推断
环境配置
tensorflow = 1.14
keras = 2.2.5
numpy = 1.19
matplotlib = 3.3.4
CPU环境配置较为简单,直接在Anaconda Prompt通过pip安装tensorflow和keras即可,注意两者版本匹配。
实验代码
#####训练代码
from keras.datasets import mnist
from keras.utils import np_utils
from keras.models import Sequential
from keras.layers.core import Dense
(X_train, y_train), (X_test, y_test) = mnist.load_data() # 读取并划分MNIST训练集、测试集
X_train = X_train.reshape(len(X_train), -1) # 二维变一维
X_test = X_test.reshape(len(X_test), -1)
X_train = X_train.astype('float32') # 转为float类型
X_test = X_test.astype('float32')
X_train = (X_train - 127) / 127 # 灰度像素数据归一化
X_test = (X_test - 127) / 127
y_train = np_utils.to_categorical(y_train, num_classes=10) # one-hot编码
y_test = np_utils.to_categorical(y_test, num_classes=10)
# 定义模型
model = Sequential() # Keras序列模型
model.add(Dense(20, input_shape=(784,), activation='relu')) # 添加全连接层(隐藏层),隐藏层数20层,激活函数为ReLU
model.add(Dense(10, activation='sigmoid')) # 添加输出层,结果10类,激活函数为Sigmoid
print(model.summary()) # 模型基本信息
model