欢迎访问我的博客首页。
环境搭建与 CUDA 介绍
- 1. GPU 与 CPU
- 2. 环境搭建
- 3. 读取设备信息
- 4. 参考
1. GPU 与 CPU
设计 CUDA 程序有三步:CPU 把需要计算的数据从内存拷贝到显存;调用核函数让 GPU 处理显存中的数据;CPU 把结果从显存拷贝到内存。CPU 叫做主机(host),GPU 叫做设备(device)。
2. 环境搭建
CUDA 编程的主要工作是使用 C++ 编写核函数。深度学习一般使用 Python,而且 Python 处理数据有得天独厚的优势,所以下面分别介绍使用 C++ 和 Python 调用核函数。
1. C++ 环境搭建
GPU 需要对应版本的驱动,驱动需要对应版本的 CUDA Toolkit,CUDA Toolkit 需要对应版本的 visual studio。此外,CUDA Toolkit 对 GPU 的算力也有要求,比如 CUDA Toolkit 9 不支持 3.0 以下算力的 GPU。安装前要弄清楚硬件和软件版本。
CUDA Toolkit 安装包中包含显卡驱动。应该先确定自己的显卡支持什么版本的 CUDA Toolkit,再确定该版本的 CUDA Toolkit 可以和哪些 visual studio 匹配。先安装好 visual studio 再安装 CUDA Toolkit。安装 CUDA Toolkit 的过程中会让选择是否安装驱动,默认是选中的,还会自动配置 visual studio 环境。
2. 安装 PyCUDA
安装 PyCUDA 前要安装 CUDA Toolkit。使用下面的命令安装 PyCUDA,如果安装出错,把下面的路径添加成环境变量。
pip install pycuda
# C:\Program Files (x86)\Windows Kits\8.1\bin\x86
3. 读取设备信息
1. 使用 C++
一般情况下,CUDA 的源代码保存在后缀为 cu 的文件中。C++ 编译器不能识别核函数模板,所以没有核函数的 CUDA 代码可以保存在后缀为 cpp 的文件中当作 C++ 编译。CMakeLists.txt 如下:
cmake_minimum_required(VERSION 3.2)
project(cuda)
set(CUDA_PATH D:\\cudatoolkit\\NVIDIA\ GPU\ Computing\ Toolkit\\CUDA\\v8.0)
include_directories(${CUDA_PATH}\\include)
link_directories(${CUDA_PATH}\\lib\\x64)
add_executable(tcuda cuda.cpp)
target_link_libraries(tcuda cudart)
一个简单的例子,用于输出显卡信息:
#include <iostream>
#include "cuda_runtime.h"
using namespace std;
int main() {
int deviceCount;
cudaGetDeviceCount(&deviceCount);
cout << "deviceCount: " << deviceCount << endl;
if (deviceCount == 0) {
cout << "error: no devices supporting CUDA.\n";
exit(EXIT_FAILURE);
}
int dev = 0;
cudaSetDevice(dev);
cudaDeviceProp devProps;
cudaGetDeviceProperties(&devProps, dev);
// 1.设备。
cout << devProps.name << endl; // GeForce 610M
cout << devProps.major << "." << devProps.minor << endl; // 2.1
cout << devProps.totalConstMem << endl; // 65536 = 2^16 = 64K
cout << devProps.totalGlobalMem << endl; // 1073741824 = 2^30 = 1G
cout << devProps.unifiedAddressing << endl; // 1
cout << devProps.warpSize << endl; // 32
// 2.多处理器。
cout << devProps.multiProcessorCount << endl; // 1
cout << devProps.maxThreadsPerMultiProcessor << endl; // 1536
for (auto x : devProps.maxGridSize) cout << x << " "; cout << endl; // 65535 65535 65535
cout << devProps.regsPerMultiprocessor << endl; // 32768 = 2^15 = 32K
cout << devProps.sharedMemPerMultiprocessor << endl; // 49152
// 3.Block。
cout << devProps.maxThreadsPerBlock << endl; // 1024
for (auto x : devProps.maxThreadsDim) cout << x << " "; cout << endl; // 1024 1024 64
cout << devProps.regsPerBlock << endl; // 32768 = 2^15 = 32K
cout << devProps.sharedMemPerBlock << endl; // 49152
}
maxThreadsPerBlock:1 个 block 内最多容纳的线程数量,一般为 1024。
warpSize:线程束的大小,一般为 32。1 个 block 最多有 1024 个线程,但只有 32 个线程可以同时执行,它们的线程编号连续,执行同一条指令处理不同的数据。每个 block 内的线程数最好设置成 32 的整数倍,如果设置 32n+x(0<x<32) 个线程,最后一次仍有 32 个线程运行,但只有前 x 个线程的工作有效。
maxThreadsPerMultiProcessor:一个多处理器最多同时调度的线程数,是 warpSize 的整数倍。
2. 使用 PyCUDA
import pycuda.driver as cuda
if __name__ == "__main__":
cuda.init()
print("Device count: %d." % cuda.Device.count())
for ordinal in range(cuda.Device.count()):
dev = cuda.Device(ordinal)
print('Device #%d name: %s.' % (ordinal, dev.name()))
print('Compute Capability: %d.%d.' % dev.compute_capability())
print('Total Memory: %s GB.' % (dev.total_memory() >> 30))
for att, value in dev.get_attributes().items():
print(att, ':', value)
4. 参考
CUDA Toolkit 下载
显卡驱动下载
安装 pycuda 出错
GPU 架构
windows 中使用 MinGW 编译 CUDA
windows 中使用 MinGW 编译 CUDA
faster-rcnn 中的 cuda
pycuda 教程