一. 基本概念
1. CUDA
2007年,NVIDIA推出CUDA(Compute Unified Device Architecture,统一计算设备架构)这个编程模型,目的是为了在应用程序中充分利用CPU和GPU各自的优点,实现CPU/GPU联合执行。这种联合执行的需要已经在最新的集中编程模型(OpenCL,OpenACC,C++ AMP)中体现出来了。
2. 并行编程语言和模型
使用比较广泛的是为可扩展的集群计算设计的消息传递接口(Message Passing Interface,MPI)和为共享存储器的多处理器系统设计的OpenMP。目前,很多HPC(High-Performance Computing)集群采用的都是异构的CPU/GPU节点模型,也就是MPI和CUDA的混合编程,来实现多机多卡模型。目前,支持CUDA的编程语言有C,C++,Fortran,Python,Java [2]。CUDA采用的是SPMD(Single-Program Multiple-Data,单程序多数据)的并行编程风格。
3. 数据并行性,任务并行性
解析:任务并行性通常对应用进行任务分解得到。例如,对一个需要做向量加法和矩阵-向量乘法的简单应用来说,每个操作可以看作一个任务。如果这两个任务可以独立地执行,那么就能得到任务并行性。
4. CUDA对C中函数声明的扩展
解析:
(1)__device__ float DeviceFunc():在设备上执行,并且只能从设备上调用。
(2)__global__ float KernelFunc():在设备上执行,并且只能从主机上调用。
(3)__host__ float HostFunc():在主机上执行,并且只能从主机上调用。
说明:如果在函数声明时没有指定CUDA扩展关键字,则默认的函数是主机函数。
5. thread,block,grid,warp,sp,sm
解析:
(1)grid、block、thread:在利用CUDA进行编程时,一个grid分为多个block,而一个block分为多个thread。
(2)sp:最基本的处理单元,最后具体的指令和任务都是在sp上处理的。
(3)sm:多个sp加上其它的一些资源(比如,存储资源、共享内存、寄储器等)组成一个sm。
(4)warp:GPU执行程序时的调度单位。目前CUDA的warp大小32,同在一个warp的线程,以不同数据资源执行相同指令。
6. CUDA核函数
kernel函数完整的执行配置参数形式是<<<Dg, Db, Ns, S>>>,如下所示:
(1)参数Dg用于定义整个grid的维度和尺寸,即一个grid有多少个block。
(2)参数Db用于定义一个block的维度和尺寸,即一个block有多少个thread。
(3)参数Ns是一个可选参数,用于设置每个block除了静态分配的shared Memory以外,最多能动态分配的shared memory大小,单位为byte。不需要动态分配时该值为0或省略不写。
(4)参数S是一个cudaStream_t类型的可选参数,初始值为零,表示该核函数处在哪个流之中。
7. CUDA存储系统
解析:每个线程拥有独立的寄存器(register)和局部存储器(local memory);每个线程块拥有独立的共享存储器(shared memory);所有线程都可以访问全局存储器(global memory),以及只读存储器常量存储器(constant memory)和纹理存储器(texture memory)。如下所示:
(1)寄存器(register)
(2)局部存储器(local memory)
(3)共享存储器(shared memory)
eg: __shared__ 数据类型 变量名;
(4)全局存储器(global memory)
(5)常量存储器(constant memory)
eg: __constant__ 数据类型 变量名;
(6)纹理存储器(texture memory)
8. CUDA SDK
9. CUDA软件栈
说明:CUDA软件栈包含多个层,设备驱动程序、应用程序编程接口(API)及其运行时、两个较高级别的通用数学库,即CUFFT和CUBLAS。相对来说,CUDA Driver是底层API,而CUDA Runtime是高层API。
10. CUDA线程组织
CUDA通过内置变量threadIdx.x、threadIdx.y、threadIdx.z表示当前线程所处的线程块的位置,blockIdx.x、blockIdx.y、blockIdx.z表示当前线程所处的线程块在整个网格中所处的位置,blockDim.x、blockDim.y、blockDim.z表示块的维度,gridDim.x、gridDim.y、gridDim.z表示网格的维度。对网格中的任意点(i, j)表征CUDA代码中的一个线程,该线程对应的网格中的索引,如下所示:
i = threadIdx.x+blockIdx.x*blockDim.x j = threadIdx.y+blockIdx.y*blockDim.y
11. 变量类型
解析:
(1)__device__:GPU的global memory空间,grid中所有线程可访问。
(2)__constant__:GPU的constant memory空间,grid中所有线程可访问。
(3)__shared__:GPU上的thread block空间,block中所有线程可访问。
(4)local:位于SM内,仅本thread可访问。
12. CUDA函数库
解析:
(1)Thrust:一个C++ STL实现的函数库。
(2)NVPP:NVIDIA性能原语(和Intel的MKK类似)。
(3)CuBLAS:BLAS(基本线性代数)函数库的GPU版本。
(4)cuFFT:GPU加速的快速傅里叶变换函数库。
(5)cuSparse:稀疏矩阵数据的线性代数和矩阵操作。
(6)Magma:LAPACK和BLAS函数库。
(7)GPU AI:基于GPU的路径规划和碰撞避免。
(8)CUDA Math Lib:支持C99标准的数学函数。
(9)Jacket:对.m代码可选的、基于GPU的Matlab引擎。
(10)Array Fire:类似于IPP、MKL和Eigen的矩阵、信号和图像处理库。
(11)CULA工具:线性代数库。
(12)IMSL:Fortran IMSL数值函数库的实现。
(13)NPP(NVIDIA Performance Primitives):提供了一系列图像和通用信号处理的函数,并且支持所有的CUDA平台。
二. Ubuntu 14.04安装CUDA 7.5
由于无论是CentOS还是Ubuntu都预装了开源的nouveau显卡驱动(SUSE没有这种问题),如果不禁用,则CUDA驱动可能不能正确安装。处理方法,如下所示:
sudo vim /etc/modprobe.d/blacklist.conf blacklist nouveau # 增加一行 sudo apt-get --purge remove xserver-xorg-video-nouveau # 把官方驱动彻底卸载 sudo apt-get --purge remove nvidia-* # 清除之前安装的任何NVIDIA驱动 sudo service lightdm stop # 进命令行,关闭Xserver sudo kill all Xorg # 杀死所有Xorg(Xorg软件包是包括显卡驱动、图形环境库等一系列软件包)说明:gksudo nvidia-settings可以进行NVIDIA X Server Settings的设置。
1. 安装依赖类库
sudo apt-get update sudo apt-get upgrade sudo apt-get install build-essential cmake g++ gfortran git pkg-config python-dev software-properties-common wget sudo apt-get autoremove sudo rm -rf /var/lib/apt/lists/*2. 安装Nvidia驱动
lspci | grep -i nvidia sudo add-apt-repository ppa:graphics-drivers/ppa sudo apt-get update sudo apt-get install nvidia-352 sudo shutdown -r now cat /proc/driver/nvidia/version3. 安装CUDA
sudo dpkg -i cuda-repo-ubuntu1404*amd64.deb # sudo apt-get update sudo apt-get install cuda echo 'export PATH=/usr/local/cuda/bin:$PATH' >> ~/.bashrc echo 'export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH' >> ~/.bashrc source ~/.bashrc nvcc -V sudo shutdown -r now4. 安装CUDA例子和测试
/usr/local/cuda/bin/cuda-install-samples-7.5.sh ~/cuda-samples cd ~/cuda-samples/NVIDIA*Samples make -j $(($(nproc) + 1)) bin/x86_64/linux/release/deviceQuery说明:至此安装完毕,就可以使用Nsight Eclipse Edition愉快地进行CUDA异构计算开发了。
参考文献:
[1] Java bindings for CUDA:http://jcuda.org/
[2] CNN之Caffe配置:http://www.cnblogs.com/alfredtofu/p/3577241.html
[3] Setting up a Deep Learning Machine from Scratch:https://github.com/saiprashanths/dl-setup
[4] CUDA初学大全:http://www.cnblogs.com/yangs/archive/2012/07/28/2613269.html
