计算机组成原理里面提到计算机必须具备五大基本组成部件:运算器、控制器、存储器、输入设备和输出设备,其中运算器和控制器必定存在于 CPU 中。然而,如果 CPU 中运算器数量特别少,我们的程序却需要进行大量的巨型矩阵的运算,使用 CPU 运行时间会特别长。我们先来简单分析一下为什么 CPU 运行时间会特别长,因为运算量非常大,同时 CPU 只能一次运算一条数据,虽然现在 CPU 普遍是多核,但是处理大量的数据还是显得力不从心。这个时候我们就不能使用 CPU 了,而应该使用 GPU,我们首先来看一下 GPU 究竟是个什么东西。
GPU
图形处理器(英语:Graphics Processing Unit,缩写:GPU),又称显示核心、视觉处理器、显示芯片,是一种专门在个人电脑、工作站、游戏机和一些移动设备(如平板电脑、智能手机等)上图像运算工作的微处理器。
考虑到 GPU 主要用来处理图像,而图像在计算机中的存储是一个二维数组或者三维数组,因此,图像的各种变换可以看作是对这个数组的各种变换。为了可以迅速做出变换,GPU 的构造就比 CPU 要复杂得多,CPU 当中只有几个大核,而 GPU 中确有几千个小核,只不过小核频率会比较低(现在普遍都是 1GHz),但是毕竟 GPU 是靠着数量取得胜利的,频率低一点其实也无所谓,因为 CPU 也并没有频率高出太多,普遍 3GHz。稍微想一下都应该知道,1 和 3 还是处在一个数量级的,而几个和几千个就不是一个数量级了,因此,我们在进行巨型矩阵的运算过程中,使用 GPU 是必须的。下面我们就来看一下如何使用 GPU 运行代码。
用 GPU 运行代码
用 GPU 运行代码的方法非常的简单,我在这里以 tensorflow 为例进行讲解。首先我们需要安装 tensorflow,直接使用 pip 安装即可。
安装完成后如图所示。
接下来我们就需要让 GPU 支持基于 tensorflow 的程序,在此之前还有一个问题,是不是所有的 GPU 都可以支持,其实不是的,官网上有提到,要求 CUDA 计算能力大于等于 3.5 的 NVIDIA GPU,查看自己 GPU 是不是 NVIDIA 的很简单,GPU-Z 就够了,查看 CUDA 算力是多少可以访问
https://developer.nvidia.com/cuda-gpus
如果硬件满足要求了就去看软件要求,如图所示。
NVIDIA 驱动程序一般一买回来就已经安装在系统中了,如果需要安装的自己去安装一下就行(注意图中的版本),接下来我们依次安装其他的软件,首先是 CUDA 工具包。
CUDA 工具包的安装
进入 CUDA 工具包下载页面,如图所示。
根据版本要求,点击选中的部分,跳转页面如图所示。
选择好对应的内容,最后点击下载即可,下载完成之后打开文件,如图所示。
修改解压路径,点击 OK,等待解压完成,解压完成后如图所示。
点击同意并继续,如图所示。
这里需要注意,千万不要选择精简,我们应该选择自定义,因为精简会把现在的显示驱动给覆盖掉,选好后点击下一步,如图所示。
然后只要是存在当前版本的组件就把前面的勾去掉,因为都装好了,再装一遍没有意义,完成后点击下一步,如图所示。
选择安装位置,点击下一步,等待安装完成,安装完成后如图所示。
点击下一步,然后点击关闭就安装完成了。
cuDNN SDK 的安装
接下来我们安装 cuDNN SDK,首先进入官网,如图所示。
点击下载 cuDNN,可能需要注册一个账号并登录,我已经登录过了,登陆后的页面如图所示。
分别按照上述步骤进行点击,下载 cuDNN,下载好了之后我们解压到指定目录,解压完成之后,需要移动或者复制三个文件。
- <cuDNN 安装路径>/cuda/bin/cudnn64_7.dll→<CUDA 安装路径>/bin
- <cuDNN 安装路径>/cuda/include/cudnn.h→<CUDA 安装路径>/include
- <cuDNN 安装路径>/cuda/lib/x64/cudnn.lib→<CUDA 安装路径>lib/x64
TensorRT 的安装
进入 TensorRT 官网,如图所示。
点击下载,然后在新页面选择好对应的信息点击下载即可。下载完成之后先解压,然后把库文件目录(<解压路径>/TensorRT-6.0.1.5/lib)添加到环境变量 PATH 中,这样就完成了安装。
GPU 测试
最后一步,我们需要测试 GPU 和 CPU 之间的差距,这个测试比较简单,就是同样的运算让 CPU 先运行,GPU 后运行,当然反过来也可以,代码如下:
代码语言:javascript复制
from time import perf_counter
import tensorflow as tf
def f(device_name, n):
with tf.device(device_name):
a = tf.random.uniform((n, n))
b = tf.random.uniform((n, n))
start = perf_counter()
print(a@b)
print(device_name, perf_counter()-start)
if __name__ == '__main__':
print(tf.config.list_logical_devices())
N = 20000
f('/device:CPU:0', N)
f('/device:GPU:0', N)
代码很简单,生成两个 N*N 的矩阵,然后相乘,我们主要看 CPU 需要运行多久,GPU 需要运行多久,其中 CPU 的运行时间和 GPU 的运行时间如下图所示。
我们可以发现 CPU 运行了将近 1 分钟,GPU 只运行了 5 秒,将近 10 倍的差距。