欢迎访问我的博客首页



环境搭建与 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 环境。

GPUDirect RDMA编程_环境搭建

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 教程