微信公众号: 点击蓝色字体小白图像与视觉进行关注

关于技术、关注yysilence00。有问题或建议,请公众号留言

  • 整理知识,学习笔记
  • 发布日记,杂文,所见所想

CUDA 并行计算 机器学习 NVCC CUDNN CUDATOOLKIT CUDA DRIVER 显卡驱动(NVIDIA Driver) 显卡(GPU)

在使用深度学习框架的过程中一定会经常碰到这些东西,虽然anaconda有时会帮助我们自动地解决这些设置,但是有些特殊的库却还是需要我们手动配置环境,但是我对标题上的这些名词其实并不十分清楚,所以老是被网上的教程绕得云里雾里,所以觉得有必要写下一篇文章当做笔记供之后参考。

  • 显卡: 简单理解这个就是我们前面说的GPU,尤其指NVIDIA公司生产的GPU系列,因为后面介绍的cuda,cudnn都是NVIDIA公司针对自身的GPU独家设计的。
  • 显卡驱动:很明显就是字面意思,通常指NVIDIA Driver,其实它就是一个驱动软件,而前面的显卡就是硬件。

  • gpu架构:Tesla、Fermi、Kepler、Maxwell、Pascal
  • 芯片型号:GT200、GK210、GM104、GF104等
  • 显卡系列:GeForce、Quadro、Tesla
  • GeForce显卡型号:G/GS、GT、GTS、GTX

gpu架构指的是硬件的设计方式,例如流处理器簇中有多少个core、是否有L1 or L2缓存、是否有双精度计算单元等等。每一代的架构是一种思想,如何去更好完成并行的思想

芯片就是对上述gpu架构思想的实现,例如芯片型号GT200中第二个字母代表是哪一代架构,有时会有100和200代的芯片,它们基本设计思路是跟这一代的架构一致,只是在细节上做了一些改变,例如GK210比GK110的寄存器就多一倍。有时候一张显卡里面可能有两张芯片,Tesla k80用了两块GK210芯片。这里第一代的gpu架构的命名也是Tesla,但现在基本已经没有这种设计的卡了,下文如果提到了会用Tesla架构和Tesla系列来进行区分。

而显卡系列在本质上并没有什么区别,只是NVIDIA希望区分成三种选择,GeFore用于家庭娱乐,Quadro用于工作站,而Tesla系列用于服务器。Tesla的k型号卡为了高性能科学计算而设计,比较突出的优点是双精度浮点运算能力高并且支持ECC内存,但是双精度能力好在深度学习训练上并没有什么卵用,所以Tesla系列又推出了M型号来做专门的训练深度学习网络的显卡。需要注意的是Tesla系列没有显示输出接口,它专注于数据计算而不是图形显示。

最后一个GeForce的显卡型号是不同的硬件定制,越往后性能越好,时钟频率越高显存越大,即G/GS<GT<GTS<GTX。

CUDA名称含义

CUDA

看了很多答案,有人说CUDA就是一门编程语言,像C,C++,python 一样,也有人说CUDA是API。CUDA英文全称是Compute Unified Device Architecture,是显卡厂商NVIDIA推出的运算平台。 CUDA™是一种由NVIDIA推出的通用并行计算架构,该架构使GPU能够解决复杂的计算问题。按照官方的说法是,CUDA是一个并行计算平台和编程模型,能够使得使用GPU进行通用计算变得简单和优雅

cudnn

这个其实就是一个专门为深度学习计算设计的软件库,里面提供了很多专门的计算函数,如卷积等。从上图也可以看到,还有很多其他的软件库和中间件,包括实现c++ STL的thrust、实现gpu版本blas的cublas、实现快速傅里叶变换的cuFFT、实现稀疏矩阵运算操作的cuSparse以及实现深度学习网络加速的cuDNN等等,具体细节可参阅GPU-Accelerated Libraries

CUDA Toolkit

参考CUDA Toolkit

CUDA Toolkit由以下组件组成:

  • Compiler: CUDA-C和CUDA-C++编译器NVCC位于bin/目录中。它建立在NVVM优化器之上,而NVVM优化器本身构建在LLVM编译器基础结构之上。希望开发人员可以使用nvm/目录下的Compiler SDK来直接针对NVVM进行开发。
  • Tools: 提供一些像profiler,debuggers等工具,这些工具可以从bin/目录中获取
  • Libraries: 下面列出的部分科学库和实用程序库可以在lib/目录中使用(Windows上的DLL位于bin/中),它们的接口在include/目录中可获取。
    • cudart: CUDA Runtime
    • cudadevrt: CUDA device runtime
    • cupti: CUDA profiling tools interface
    • nvml: NVIDIA management library
    • nvrtc: CUDA runtime compilation
    • cublas: BLAS (Basic Linear Algebra Subprograms,基础线性代数程序集)
    • cublas_device: BLAS kernel interface
    • ...
  • CUDA Samples: 演示如何使用各种CUDA和library API的代码示例。可在Linux和Mac上的samples/目录中获得,Windows上的路径是C:\ProgramData\NVIDIA Corporation\CUDA Samples中。在Linux和Mac上,samples/目录是只读的,如果要对它们进行修改,则必须将这些示例复制到另一个位置。
  • CUDA Driver: 运行CUDA应用程序需要系统至少有一个具有CUDA功能的GPU与CUDA工具包兼容的驱动程序。每个版本的CUDA工具包都对应一个最低版本的CUDA Driver,也就是说如果你安装的CUDA Driver版本比官方推荐的还低,那么很可能会无法正常运行。CUDA Driver是向后兼容的,这意味着根据CUDA的特定版本编译的应用程序将继续在后续发布的Driver上也能继续工作。通常为了方便,在安装CUDA Toolkit的时候会默认安装CUDA Driver。在开发阶段可以选择默认安装Driver,但是对于像Tesla GPU这样的商用情况时,建议在官方安装最新版本的Driver。
    目前(2019年10月)的CUDA Toolkit和CUDA Driver版本的对应情况如下:
CUDA Toolkit Linux x86_64 Driver Version Windows x86_64 Driver Version
CUDA 10.1 (10.1.105 general release, and updates) >= 418.39 >= 418.96
CUDA 10.0.130 >= 410.48 >= 411.31
CUDA 9.2 (9.2.148 Update 1) >= 396.37 >= 398.26
CUDA 9.2 (9.2.88) >= 396.26 >= 397.44
CUDA 9.1 (9.1.85) >= 390.46 >= 391.29
CUDA 9.0 (9.0.76) >= 384.81 >= 385.54
CUDA 8.0 (8.0.61 GA2) >= 375.26 >= 376.51
CUDA 8.0 (8.0.44) >= 367.48 >= 369.30
CUDA 7.5 (7.5.16) >= 352.31 >= 353.66
CUDA 7.0 (7.0.28) >= 346.46 >= 347.62

nvcc&nvidia-smi

nvcc

这个在前面已经介绍了,nvcc其实就是CUDA的编译器,可以从CUDA Toolkit的/bin目录中获取,类似于gcc就是c语言的编译器。由于程序是要经过编译器编程成可执行的二进制文件,而cuda程序有两种代码,一种是运行在cpu上的host代码,一种是运行在gpu上的device代码,所以nvcc编译器要保证两部分代码能够编译成二进制文件在不同的机器上执行。nvcc涉及到的文件后缀及相关意义如下表

文件后缀 意义
.cu cuda源文件,包括host和device代码
.cup 经过预处理的cuda源文件,编译选项--preprocess/-E
.c c源文件
.cc/.cxx/.cpp c++源文件
.gpu gpu中间文件,编译选项--gpu
.ptx 类似汇编代码,编译选项--ptx
.o/.obj 目标文件,编译选项--compile/-c
.a/.lib 库文件,编译选项--lib/-lib
.res 资源文件
.so 共享目标文件,编译选项--shared/-shared
.cubin cuda的二进制文件,编译选项-cubin

nvidia-smi

nvidia-smi全程是NVIDIA System Management Interface ,它是一个基于前面介绍过的NVIDIA Management Library(NVML)构建的命令行实用工具,旨在帮助管理和监控NVIDIA GPU设备。

nvccnvidia-smi显示的CUDA版本不同?

在我们实验室的服务器上nvcc --version显示的结果如下:

nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2018 NVIDIA Corporation
Built on Tue_Jun_12_23:07:04_CDT_2018
Cuda compilation tools, release 9.2, V9.2.148

nvidia-smi显示结果如下:

+-----------------------------------------------------------------------------+
| NVIDIA-SMI 410.104      Driver Version: 410.104      CUDA Version: 10.0     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  Tesla V100-PCIE...  On   | 00000000:01:00.0 Off |                  Off |
| N/A   28C    P0    26W / 250W |      0MiB / 16130MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   1  Tesla P100-PCIE...  On   | 00000000:02:00.0 Off |                  Off |
| N/A   24C    P0    30W / 250W |      0MiB / 16280MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+

±----------------------------------------------------------------------------+
| Processes: GPU Memory |
| GPU PID Type Process name Usage |
|=============================================================================|
| No running processes found |
±----------------------------------------------------------------------------+

可以看到nvcc的CUDA 版本是9.2,而nvidia-smi的CUDA版本是10.0。很奇怪的是有时候绝大多数情况代码也能整成跑起来,stackoverflow上的一个解释如下:

CUDA有两个主要的API:runtime(运行时) APIdriver API。这两个API都有对应的CUDA版本(如9.2和10.0等)。

  • 用于支持driver API的必要文件(如libcuda.so)是由GPU driver installer安装的。nvidia-smi就属于这一类API。
  • 用于支持runtime API的必要文件(如libcudart.so以及nvcc)是由CUDA Toolkit installer安装的。(CUDA Toolkit Installer有时可能会集成了GPU driver Installer)。nvcc是与CUDA Toolkit一起安装的CUDA compiler-driver tool,它只知道它自身构建时的CUDA runtime版本。它不知道安装了什么版本的GPU driver,甚至不知道是否安装了GPU driver。

综上,如果driver API和runtime API的CUDA版本不一致可能是因为你使用的是单独的GPU driver installer,而不是CUDA Toolkit installer里的GPU driver installer。

runtime和driver API区别

下图很清楚的展示前面提到的各种概念之间的关系,其中runtime和driver API在很多情况非常相似,也就是说用起来的效果是等价的,但是你不能混合使用这两个API,因为二者是互斥的。也就是说在开发过程中,你只能选择其中一种API。简单理解二者的区别就是:runtime是更高级的封装,开发人员用起来更方便,而driver API更接近底层,速度可能会更快。

两种API详细的区别如下:

  • 复杂性

    • runtime API通过提供隐式初始化、上下文管理和模块管理来简化设备代码管理。这使得代码更简单,但也缺乏驱动程序API所具有的控制级别。
    • 相比之下,driver API提供了更细粒度的控制,特别是在上下文和模块加载方面。实现内核启动要复杂得多,因为执行配置和内核参数必须用显式函数调用指定。
  • 控制
    • 对于runtime API,其在运行时,所有内核都在初始化期间自动加载,并在程序运行期间保持加载状态。
    • 而使用driver API,可以只加载当前需要的模块,甚至动态地重新加载模块。driver API也是语言独立的,因为它只处理cubin对象。
  • 上下文管理
    上下文管理可以通过driver API完成,但是在runtime API中不公开。相反,runtime API自己决定为线程使用哪个上下文:

    • 如果一个上下文通过driver API成为调用线程的当前上下文,runtime将使用它,
    • 如果没有这样的上下文,它将使用“主上下文(primary context)”。

主上下文会根据需要创建,每个设备每个进程一个上下文,并进行引用计数,然后在没有更多的引用时销毁它们。在一个进程中,所有runtime API的用户都将共享主上下文,除非上下文已成为每个线程的当前上下文。runtime使用的上下文,即当前上下文或主上下文,可以用cudaDeviceSynchronize()同步,也可以用cudaDeviceReset()销毁。
但是,将runtime API与主上下文一起使用会有tradeoff。例如,对于那些需要给较大的软件包写插件的开发者来说者会带来不少麻烦,因为如果所有的插件都在同一个进程中运行,它们将共享一个上下文,但可能无法相互通信。也就是说,如果其中一个在完成所有CUDA工作后调用cudaDeviceReset(),其他插件将失败,因为它们使用的上下文在它们不知情的情况下被破坏。为了避免这个问题,CUDA clients可以使用driver API来创建和设置当前上下文,然后使用runtime API来处理它。但是,上下文可能会消耗大量的资源,比如设备内存、额外的主机线程和设备上上下文切换的性能成本。当将driver API与基于runtime API(如cuBLAS或cuFFT)构建的库一起使用时,这种runtime-driver上下文共享非常重要。

Linux中PATH、 LIBRARY_PATH、 LD_LIBRARY_PATH的区别

参考Linux中PATH、 LIBRARY_PATH、 LD_LIBRARY_PATH的区别

PATH

PATH是可执行文件路径,是三个中我们最常接触到的,因为我们命令行中的每句能运行的命令,如ls、top、ps等,都是系统通过PATH找到了这个命令执行文件的所在位置,再run这个命令(可执行文件)。 比如说,在用户的目录~/mycode/下有一个bin文件夹,里面放了有可执行的二进制文件、shell脚本等。如果想要在任意目录下都能运行上述bin文件夹的可执行文件,那么只需要把这个bin的路径添加到PATH即可,方法如下:

# vim ~/.bashrc
PATH=$PATH:~/mycode/bin

LIBRARY_PATH和LD_LIBRARY_PATH

这两个路径可以放在一起讨论,

  • LIBRARY_PATH程序编译期间查找动态链接库时指定查找共享库的路径
  • LD_LIBRARY_PATH程序加载运行期间查找动态链接库时指定除了系统默认路径之外的其他路径

两者的共同点是库,库是这两个路径和PATH路径的区别,PATH是可执行文件。

两者的差异点是使用时间不一样。一个是编译期,对应的是开发阶段,如gcc编译;一个是加载运行期,对应的是程序已交付的使用阶段。

配置方法也是类似:

export  LD_LIBRARY_PATH=LD_LIBRARY_PATH:XXXX

多版本CUDA切换

参考安装多版本cuda,多版本之间切换

基于前面几个小节的介绍,现在再来介绍如何管理多版本CUDA就会好懂很多了。

cuda 的下载与安装方法选择

到 CUDA Toolkit Download 下载所需版本,以 cuda_9.0.176_384.81_linux.run为例:

建议选择使用 .run 文件安装,因为使用 .deb可能会将已经安装的较新的显卡驱动替换。

cuda 安装

进入到放置 cuda_9.0.176_384.81_linux.run 的目录:

sudo chmod +x cuda_9.0.176_384.81_linux.run # 为 cuda_9.0.176_384.81_linux.run 添加可执行权限
./cuda_9.0.176_384.81_linux.run # 安装 cuda_9.0.176_384.81_linux.run

在安装过程中截取其中比较重要的几个选择:

Do you accept the previously read EULA?
accept/decline/quit: accept

Install NVIDIA Accelerated Graphics Driver for Linux-x86_64 384.81?
(y)es/(n)o/(q)uit: n # 如果在这之前已经安装好更高版本的显卡驱动就不需要再重复安装,如果需要重复安装就选择 yes,此外还需要关闭图形界面。

Install the CUDA 9.0 Toolkit?
(y)es/(n)o/(q)uit: y

Enter Toolkit Location
[ default is /usr/local/cuda-9.0 ]: # 一般选择默认即可,也可以选择安装在其他目录,在需要用的时候指向该目录或者使用软连接 link 到 /usr/local/cuda。

/usr/local/cuda-9.0 is not writable.
Do you wish to run the installation with 'sudo'?
(y)es/(n)o: y

Please enter your password:
Do you want to install a symbolic link at /usr/local/cuda? # 是否将安装目录通过软连接的方式 link 到 /usr/local/cuda,yes or no 都可以,取决于你是否使用 /usr/local/cuda 为默认的 cuda 目录。
(y)es/(n)o/(q)uit: n

Install the CUDA 9.0 Samples?
(y)es/(n)o/(q)uit: n

前面选择的一些汇总:

Driver:   Not Selected
Toolkit:  Installed in /usr/local/cuda-9.0
Samples:  Not Selected

Please make sure that

  • PATH includes /usr/local/cuda-9.0/bin
  • LD_LIBRARY_PATH includes /usr/local/cuda-9.0/lib64, or, add /usr/local/cuda-9.0/lib64 to /etc/ld.so.conf and run ldconfig as root

To uninstall the CUDA Toolkit, run the uninstall script in /usr/local/cuda-9.0/bin

Please see CUDA_Installation_Guide_Linux.pdf in /usr/local/cuda-9.0/doc/pdf for detailed information on setting up CUDA.

***WARNING: Incomplete installation! This installation did not install the CUDA Driver. A driver of version at least 384.00 is required for CUDA 9.0 functionality to work.
To install the driver using this installer, run the following command, replacing <CudaInstaller> with the name of this run file:
sudo <CudaInstaller>.run -silent -driver

安装完成后可以在 /usr/local 目录下看到:

cuda-8.0 # 笔者之前安装的cuda-8.0
cuda-9.0 # 刚刚安装的cuda-9.0
cuda # cuda-8.0 的软连接

多个 cuda 版本之间进行切换

~/.bashrc 或 ~/.zshrc 下与cuda相关的路径都改为 /usr/local/cuda/ 而不使用 /usr/local/cuda-8.0//usr/local/cuda-9.0/

#在切换cuda版本时
rm -rf /usr/local/cuda#删除之前创建的软链接
sudo ln -s /usr/local/cuda-8.0/ /usr/local/cuda/
nvcc --version #查看当前 cuda 版本

nvcc: NVIDIA ® Cuda compiler driver
Copyright © 2005-2016 NVIDIA Corporation
Built on Mon_Jan_23_12:24:11_CST_2017
Cuda compilation tools, release 8.0, V8.0.62

#cuda8.0 切换到 cuda9.0
rm -rf /usr/local/cuda
sudo ln -s /usr/local/cuda-9.0/ /usr/local/cuda/
nvcc --version

GPU 型号含义

参考【GPU 编程系列之一】从深度学习选择什么样的 gpu 来谈谈 gpu 的硬件架构

  • 显卡: 简单理解这个就是我们前面说的GPU,尤其指 NVIDIA 公司生产的 GPU 系列,因为后面介绍的 cuda,cudnn 都是 NVIDIA 公司针对自身的 GPU 独家设计的。

  • 显卡驱动:很明显就是字面意思,通常指NVIDIA Driver,其实它就是一个驱动软件,而前面的显卡就是硬件。

  • gpu 架构:Tesla、Fermi、Kepler、Maxwell、Pascal

  • 芯片型号:GT200、GK210、GM104、GF104 等

  • 显卡系列:GeForce、Quadro、Tesla

  • GeForce 显卡型号:G/GS、GT、GTS、GTX

gpu 架构指的是硬件的设计方式,例如流处理器簇中有多少个 core、是否有 L1 or L2 缓存、是否有双精度计算单元等等。每一代的架构是一种思想,如何去更好完成并行的思想

芯片就是对上述 gpu 架构思想的实现,例如芯片型号 GT200 中第二个字母代表是哪一代架构,有时会有 100 和 200 代的芯片,它们基本设计思路是跟这一代的架构一致,只是在细节上做了一些改变,例如 GK210 比 GK110 的寄存器就多一倍。有时候一张显卡里面可能有两张芯片,Tesla k80 用了两块 GK210 芯片。这里第一代的 gpu 架构的命名也是 Tesla,但现在基本已经没有这种设计的卡了,下文如果提到了会用 Tesla 架构和 Tesla 系列来进行区分。

而显卡系列在本质上并没有什么区别,只是 NVIDIA 希望区分成三种选择,GeFore 用于家庭娱乐,Quadro 用于工作站,而 Tesla 系列用于服务器。Tesla 的 k 型号卡为了高性能科学计算而设计,比较突出的优点是双精度浮点运算能力高并且支持 ECC 内存,但是双精度能力好在深度学习训练上并没有什么卵用,所以 Tesla 系列又推出了 M 型号来做专门的训练深度学习网络的显卡。需要注意的是 Tesla 系列没有显示输出接口,它专注于数据计算而不是图形显示。

最后一个 GeForce 的显卡型号是不同的硬件定制,越往后性能越好,时钟频率越高显存越大,即 G/GS<GT<GTS<GTX。

CUDA 名称含义

CUDA

看了很多答案,有人说 CUDA 就是一门编程语言,像 C,C++,python 一样,也有人说 CUDA 是 API。CUDA 英文全称是 Compute Unified Device Architecture,是显卡厂商 NVIDIA 推出的运算平台。 CUDA™ 是一种由 NVIDIA 推出的通用并行计算架构,该架构使 GPU 能够解决复杂的计算问题。按照官方的说法是,CUDA 是一个并行计算平台和编程模型,能够使得使用 GPU 进行通用计算变得简单和优雅

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hYHCyodC-1591759780854)(https://ask.qcloudimg.com/draft/1215004/tflrie3lx8.png)]

cudnn

这个其实就是一个专门为深度学习计算设计的软件库,里面提供了很多专门的计算函数,如卷积等。从上图也可以看到,还有很多其他的软件库和中间件,包括实现 c++ STL 的 thrust、实现 gpu 版本 blas 的 cublas、实现快速傅里叶变换的 cuFFT、实现稀疏矩阵运算操作的 cuSparse 以及实现深度学习网络加速的 cuDNN 等等,具体细节可参阅GPU-Accelerated Libraries

CUDA Toolkit

参考CUDA Toolkit

CUDA Toolkit 由以下组件组成:

  • Compiler: CUDA-C 和 CUDA-C++编译器NVCC位于bin/目录中。它建立在NVVM优化器之上,而NVVM优化器本身构建在LLVM编译器基础结构之上。希望开发人员可以使用nvm/目录下的 Compiler SDK 来直接针对 NVVM 进行开发。
  • Tools: 提供一些像profiler,debuggers等工具,这些工具可以从bin/目录中获取
  • Libraries: 下面列出的部分科学库和实用程序库可以在lib/目录中使用(Windows 上的 DLL 位于bin/中),它们的接口在include/目录中可获取。
    • cudart: CUDA Runtime
    • cudadevrt: CUDA device runtime
    • cupti: CUDA profiling tools interface
    • nvml: NVIDIA management library
    • nvrtc: CUDA runtime compilation
    • cublas: BLAS (Basic Linear Algebra Subprograms,基础线性代数程序集)
    • cublas_device: BLAS kernel interface
  • CUDA Samples: 演示如何使用各种 CUDA 和 library API 的代码示例。可在 Linux 和 Mac 上的samples/目录中获得,Windows 上的路径是C:\ProgramData\NVIDIA Corporation\CUDA Samples中。在 Linux 和 Mac 上,samples/目录是只读的,如果要对它们进行修改,则必须将这些示例复制到另一个位置。
  • CUDA Driver: 运行 CUDA 应用程序需要系统至少有一个具有 CUDA 功能的 GPU与 CUDA 工具包兼容的驱动程序。每个版本的 CUDA 工具包都对应一个最低版本的 CUDA Driver,也就是说如果你安装的 CUDA Driver 版本比官方推荐的还低,那么很可能会无法正常运行。CUDA Driver 是向后兼容的,这意味着根据 CUDA 的特定版本编译的应用程序将继续在后续发布的 Driver 上也能继续工作。通常为了方便,在安装 CUDA Toolkit 的时候会默认安装 CUDA Driver。在开发阶段可以选择默认安装 Driver,但是对于像 Tesla GPU 这样的商用情况时,建议在官方安装最新版本的 Driver。
    目前(2019 年 10 月)的 CUDA Toolkit 和 CUDA Driver 版本的对应情况如下:

CUDA Toolkit

Linux x86_64 Driver Version

Windows x86_64 Driver Version

CUDA 10.1 (10.1.105 general release, and updates)

= 418.39

= 418.96

CUDA 10.0.130

= 410.48

= 411.31

CUDA 9.2 (9.2.148 Update 1)

= 396.37

= 398.26

CUDA 9.2 (9.2.88)

= 396.26

= 397.44

CUDA 9.1 (9.1.85)

= 390.46

= 391.29

CUDA 9.0 (9.0.76)

= 384.81

= 385.54

CUDA 8.0 (8.0.61 GA2)

= 375.26

= 376.51

CUDA 8.0 (8.0.44)

= 367.48

= 369.30

CUDA 7.5 (7.5.16)

= 352.31

= 353.66

CUDA 7.0 (7.0.28)

= 346.46

= 347.62

nvcc&nvidia-smi

nvcc

这个在前面已经介绍了,nvcc其实就是 CUDA 的编译器,可以从 CUDA Toolkit 的/bin目录中获取,类似于gcc就是 c 语言的编译器。由于程序是要经过编译器编程成可执行的二进制文件,而 cuda 程序有两种代码,一种是运行在 cpu 上的 host 代码,一种是运行在 gpu 上的 device 代码,所以nvcc编译器要保证两部分代码能够编译成二进制文件在不同的机器上执行。nvcc 涉及到的文件后缀及相关意义如下表

文件后缀

意义

.cu

cuda 源文件,包括 host 和 device 代码

.cup

经过预处理的 cuda 源文件,编译选项–preprocess/-E

.c

c 源文件

.cc/.cxx/.cpp

c++源文件

.gpu

gpu 中间文件,编译选项–gpu

.ptx

类似汇编代码,编译选项–ptx

.o/.obj

目标文件,编译选项–compile/-c

.a/.lib

库文件,编译选项–lib/-lib

.res

资源文件

.so

共享目标文件,编译选项–shared/-shared

.cubin

cuda 的二进制文件,编译选项-cubin

nvidia-smi

nvidia-smi全程是 NVIDIA System Management Interface ,它是一个基于前面介绍过的NVIDIA Management Library(NVML)构建的命令行实用工具,旨在帮助管理和监控 NVIDIA GPU 设备。

nvccnvidia-smi显示的 CUDA 版本不同?

在我们实验室的服务器上nvcc --version显示的结果如下:

nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2018 NVIDIA Corporation
Built on Tue_Jun_12_23:07:04_CDT_2018
Cuda compilation tools, release 9.2, V9.2.148

nvidia-smi显示结果如下:

+-----------------------------------------------------------------------------+
| NVIDIA-SMI 410.104      Driver Version: 410.104      CUDA Version: 10.0     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  Tesla V100-PCIE...  On   | 00000000:01:00.0 Off |                  Off |
| N/A   28C    P0    26W / 250W |      0MiB / 16130MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
|   1  Tesla P100-PCIE...  On   | 00000000:02:00.0 Off |                  Off |
| N/A   24C    P0    30W / 250W |      0MiB / 16280MiB |      0%      Default |
+-------------------------------+----------------------+----------------------++-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+

可以看到nvcc的 CUDA 版本是 9.2,而nvidia-smi的 CUDA 版本是 10.0。很奇怪的是有时候绝大多数情况代码也能整成跑起来,stackoverflow上的一个解释如下:

CUDA 有两个主要的 API:runtime(运行时) APIdriver API。这两个 API 都有对应的 CUDA 版本(如 9.2 和 10.0 等)。

  • 用于支持driver API的必要文件(如libcuda.so)是由GPU driver installer安装的。nvidia-smi就属于这一类 API。
  • 用于支持runtime API的必要文件(如libcudart.so以及nvcc)是由CUDA Toolkit installer安装的。(CUDA Toolkit Installer 有时可能会集成了 GPU driver Installer)。nvcc是与 CUDA Toolkit 一起安装的 CUDA compiler-driver tool,它只知道它自身构建时的 CUDA runtime 版本。它不知道安装了什么版本的 GPU driver,甚至不知道是否安装了 GPU driver。

综上,如果 driver API 和 runtime API 的 CUDA 版本不一致可能是因为你使用的是单独的 GPU driver installer,而不是 CUDA Toolkit installer 里的 GPU driver installer。

runtime 和 driver API 区别

下图很清楚的展示前面提到的各种概念之间的关系,其中 runtime 和 driver API 在很多情况非常相似,也就是说用起来的效果是等价的,但是你不能混合使用这两个 API,因为二者是互斥的。也就是说在开发过程中,你只能选择其中一种 API。简单理解二者的区别就是:runtime 是更高级的封装,开发人员用起来更方便,而 driver API 更接近底层,速度可能会更快。

两种 API 详细的区别如下:

  • 复杂性

    • runtime API 通过提供隐式初始化、上下文管理和模块管理来简化设备代码管理。这使得代码更简单,但也缺乏驱动程序 API 所具有的控制级别。
    • 相比之下,driver API 提供了更细粒度的控制,特别是在上下文和模块加载方面。实现内核启动要复杂得多,因为执行配置和内核参数必须用显式函数调用指定。
  • 控制
    • 对于 runtime API,其在运行时,所有内核都在初始化期间自动加载,并在程序运行期间保持加载状态。
    • 而使用 driver API,可以只加载当前需要的模块,甚至动态地重新加载模块。driver API 也是语言独立的,因为它只处理cubin对象。
  • 上下文管理
    上下文管理可以通过 driver API 完成,但是在 runtime API 中不公开。相反,runtime API 自己决定为线程使用哪个上下文:

    • 如果一个上下文通过 driver API 成为调用线程的当前上下文,runtime 将使用它,
    • 如果没有这样的上下文,它将使用“主上下文(primary context)”。

主上下文会根据需要创建,每个设备每个进程一个上下文,并进行引用计数,然后在没有更多的引用时销毁它们。在一个进程中,所有 runtime API 的用户都将共享主上下文,除非上下文已成为每个线程的当前上下文。runtime 使用的上下文,即当前上下文或主上下文,可以用cudaDeviceSynchronize()同步,也可以用cudaDeviceReset()销毁。
但是,将 runtime API 与主上下文一起使用会有 tradeoff。例如,对于那些需要给较大的软件包写插件的开发者来说者会带来不少麻烦,因为如果所有的插件都在同一个进程中运行,它们将共享一个上下文,但可能无法相互通信。也就是说,如果其中一个在完成所有 CUDA 工作后调用cudaDeviceReset(),其他插件将失败,因为它们使用的上下文在它们不知情的情况下被破坏。为了避免这个问题,CUDA clients 可以使用 driver API 来创建和设置当前上下文,然后使用 runtime API 来处理它。但是,上下文可能会消耗大量的资源,比如设备内存、额外的主机线程和设备上上下文切换的性能成本。当将 driver API 与基于 runtime API(如 cuBLAS 或 cuFFT)构建的库一起使用时,这种 runtime-driver 上下文共享非常重要。

Linux 中 PATH、 LIBRARY_PATH、 LD_LIBRARY_PATH 的区别

参考Linux 中 PATH、 LIBRARY_PATH、 LD_LIBRARY_PATH 的区别

PATH

PATH 是可执行文件路径,是三个中我们最常接触到的,因为我们命令行中的每句能运行的命令,如 ls、top、ps 等,都是系统通过 PATH 找到了这个命令执行文件的所在位置,再 run 这个命令(可执行文件)。 比如说,在用户的目录~/mycode/下有一个 bin 文件夹,里面放了有可执行的二进制文件、shell 脚本等。如果想要在任意目录下都能运行上述 bin 文件夹的可执行文件,那么只需要把这个 bin 的路径添加到 PATH 即可,方法如下:

# vim ~/.bashrc
PATH=$PATH:~/mycode/bin

LIBRARY_PATH 和 LD_LIBRARY_PATH

这两个路径可以放在一起讨论,

  • LIBRARY_PATH程序编译期间查找动态链接库时指定查找共享库的路径
  • LD_LIBRARY_PATH程序加载运行期间查找动态链接库时指定除了系统默认路径之外的其他路径

两者的共同点是库,库是这两个路径和 PATH 路径的区别,PATH 是可执行文件。

两者的差异点是使用时间不一样。一个是编译期,对应的是开发阶段,如 gcc 编译;一个是加载运行期,对应的是程序已交付的使用阶段。

配置方法也是类似:

export  LD_LIBRARY_PATH=LD_LIBRARY_PATH:XXXX

多版本 CUDA 切换

参考安装多版本 cuda,多版本之间切换

基于前面几个小节的介绍,现在再来介绍如何管理多版本 CUDA 就会好懂很多了。

cuda 的下载与安装方法选择

到 CUDA Toolkit Download 下载所需版本,以 cuda_9.0.176_384.81_linux.run 为例:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GzFJkRjP-1591759780867)(https://ask.qcloudimg.com/draft/1215004/g9v7k11jem.png)]

建议选择使用 .run 文件安装,因为使用 .deb可能会将已经安装的较新的显卡驱动替换。

cuda 安装

进入到放置 cuda_9.0.176_384.81_linux.run 的目录:

sudo chmod +x cuda_9.0.176_384.81_linux.run # 为 cuda_9.0.176_384.81_linux.run 添加可执行权限
./cuda_9.0.176_384.81_linux.run # 安装 cuda_9.0.176_384.81_linux.run

在安装过程中截取其中比较重要的几个选择:

Do you accept the previously read EULA?
accept/decline/quit: acceptInstall NVIDIA Accelerated Graphics Driver for Linux-x86_64 384.81?
(y)es/(n)o/(q)uit: n # 如果在这之前已经安装好更高版本的显卡驱动就不需要再重复安装,如果需要重复安装就选择 yes,此外还需要关闭图形界面。Install the CUDA 9.0 Toolkit?
(y)es/(n)o/(q)uit: yEnter Toolkit Location[ default is /usr/local/cuda-9.0 ]: # 一般选择默认即可,也可以选择安装在其他目录,在需要用的时候指向该目录或者使用软连接 link 到 /usr/local/cuda。/usr/local/cuda-9.0 is not writable.
Do you wish to run the installation with 'sudo'?
(y)es/(n)o: yPlease enter your password:
Do you want to install a symbolic link at /usr/local/cuda? # 是否将安装目录通过软连接的方式 link 到 /usr/local/cuda,yes or no 都可以,取决于你是否使用 /usr/local/cuda 为默认的 cuda 目录。
(y)es/(n)o/(q)uit: nInstall the CUDA 9.0 Samples?
(y)es/(n)o/(q)uit: n

前面选择的一些汇总:

Driver:   Not Selected
Toolkit:  Installed in /usr/local/cuda-9.0
Samples:  Not SelectedPlease make sure that-   PATH includes /usr/local/cuda-9.0/bin-   LD_LIBRARY_PATH includes /usr/local/cuda-9.0/lib64, or, add /usr/local/cuda-9.0/lib64 to /etc/ld.so.conf and run ldconfig as rootTo uninstall the CUDA Toolkit, run the uninstall script in /usr/local/cuda-9.0/binPlease see CUDA_Installation_Guide_Linux.pdf in /usr/local/cuda-9.0/doc/pdf for detailed information on setting up CUDA.***WARNING: Incomplete installation! This installation did not install the CUDA Driver. A driver of version at least 384.00 is required for CUDA 9.0 functionality to work.
To install the driver using this installer, run the following command, replacing <CudaInstaller> with the name of this run file:sudo <CudaInstaller>.run -silent -driver

安装完成后可以在 /usr/local 目录下看到:

cuda-8.0 # 笔者之前安装的cuda-8.0
cuda-9.0 # 刚刚安装的cuda-9.0
cuda # cuda-8.0 的软连接

多个 cuda 版本之间进行切换

~/.bashrc 或 ~/.zshrc 下与 cuda 相关的路径都改为 /usr/local/cuda/ 而不使用 /usr/local/cuda-8.0//usr/local/cuda-9.0/

#在切换cuda版本时
rm -rf /usr/local/cuda#删除之前创建的软链接
sudo ln -s /usr/local/cuda-8.0/ /usr/local/cuda/
nvcc --version #查看当前 cuda 版本nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2016 NVIDIA Corporation
Built on Mon_Jan_23_12:24:11_CST_2017
Cuda compilation tools, release 8.0, V8.0.62#cuda8.0 切换到 cuda9.0
rm -rf /usr/local/cuda
sudo ln -s /usr/local/cuda-9.0/ /usr/local/cuda/
nvcc --version

这篇文章花了我一天的时间来整理,所以如果觉得有帮助给个赞可好。

更多请扫码关注

CUDA 并行计算 机器学习 NVCC CUDNN CUDATOOLKIT CUDA DRIVER 显卡驱动(NVIDIA Driver) 显卡(GPU)相关推荐

  1. 【详细】linux系统安装显卡驱动(Nvidia driver) + cuda10.2

    安装概览 安装驱动 安装cuda 1 Nvidia driver安装 1.1 查看电脑GPU型号 lspci | grep -i nvidia 我的电脑显示结果如下: 即型号为Tesla K800 1 ...

  2. Ubuntu 16.04 - GeForce RTX 2080 Ti 安装 GPU 显卡驱动 (Display Driver)

    Ubuntu 16.04 - GeForce RTX 2080 Ti 安装 GPU 显卡驱动 (Display Driver) NVIDIA 引领人工智能计算 - NVIDIA https://www ...

  3. Ubuntu12.10中安装ati显卡驱动amd driver 13.1

    1. 先安装依赖库 [plain] view plaincopyprint? sudo apt-get install build-essential cdbs dh-make dkms execst ...

  4. [Tensorflow] Ubuntu下NVIDIA Driver+CUDA+cuDNN 安装踩坑总结

    最近安装了3台workstation, 显卡分布是Quadro P2000, Quadro K220和Quadro 2000.其中第一台工作站是去年新入的,另外两台都是3-5年历史的旧机器了. 第一台 ...

  5. ubuntu22.04安装显卡驱动、CUDA及cudnn

    安装显卡驱动.CUDA及cudnn 显卡驱动 自行下载安装 Software & Updates安装 使用命令安行安装 Ubuntu22.04系统安装CUDA 一.CUDA 是什么 先查看有没 ...

  6. Ubuntu系统装机流程(显卡驱动、cuda、cudnn、搜狗输入法、anaconda、pycharm)

    整体流程 一.安装Ubuntu18.04系统 二.安装显卡驱动 三.安装Cuda 四.安装Cudnn 五.安装搜狗输入法 六.安装Anaconda 七.安装Pycharm社区版 一.安装Ubuntu1 ...

  7. 显卡、显卡驱动、cuda、cudnn 通俗解释及深度学习环境搭建

    场景描述 搞深度学习时需要先搭建环境,需要折腾显卡驱动.cuda.cudnn.以及各种深度学习框架(TensorFlow.Pytorch等).光听这些名词有好些人都迷糊了,更不要提解决他们之间的不兼容 ...

  8. NVIDIA显卡驱动旧版本下载安装+CUDA下载+cudnn下载+解决CUDNN_STATUS_INTERNAL_ERROR+Failed to call ThenRnnForward

    重新装显卡驱动431版本+CUDA+cudnn,解决CUDNN_STATUS_INTERNAL_ERROR+Failed to call ThenRnnForward with model confi ...

  9. 查看显卡支持的CUDA版本号 CUDA与显卡驱动版本

    前言: 应项目需要,要在自己的电脑上安装TensorFlow-GPU版本 若要安装GPU版本则必须要安装CUDA 以下为配合 Win10上搭建TensorFlow(GPU)的学习笔记而做了简单记录. ...

最新文章

  1. docker注册表回传失败 群晖6.2_Glances实时监视群晖运行状况
  2. java crontriggerbean_spring定时器----CronTriggerBean
  3. DNN数据库核心表结构及设计思路探研
  4. 广汽研究院BMS软件工程师_八大高手齐聚CATIA决赛,3人获“广汽技术创新能手”...
  5. 学习记录-交叉编译环境的设置
  6. saleor的生产环境部署-失败记录
  7. jboss配置ejb容器_JBoss AS 7 EJB3池配置
  8. Python学习笔记之列表(一)
  9. c语言中sizeof是一个标准库函数,对C语言中的sizeof的介绍分析
  10. 怎么把VC++的注释语句调成其他颜色,只调注释语句
  11. 多线程编程-之并发编程:同步容器
  12. 电驴服务器搜索文件排序,eMule如何搜索文件
  13. 保存特定模式的snp文件
  14. WinCE下Touch Panel驱动介绍 .
  15. java数字转大写_java实现数字转大写的方法
  16. 发包Byte速率和发包个数速率和带宽的关系
  17. kd树的根节点_多维空间分割树--KD树
  18. 博客群建软件-关键词要如何优化才能有好的排名
  19. MATLAB 中gcf、gca 以及gco三者的解析
  20. 置换密码及其python实现

热门文章

  1. 图像分割后再将图片拼接在一起
  2. Saxon cannot write a DOMResult unless saxon9-dom.jar is on the classpath
  3. cmd 如何在bat文件中调用另一个bat文件
  4. 数据仓库数据同步策略
  5. 贪心算法 | 473火柴拼正方形 怎么用C++实现摆放火柴棍?
  6. 2021年山东省安全员C证考试报名及山东省安全员C证新版试题
  7. 如何在GitHub中上传图片
  8. 全球风投在一周内向非洲金融科技注资近4亿美元
  9. 巴塞尔协议中银行风险划分
  10. 静态心电设备的数据采集(aECG)