CUDA学习笔记(四)device管理

本篇博文转载于https://www.cnblogs.com/1024incn/tag/CUDA/,仅用于学习。

device管理

NVIDIA提供了集中凡是来查询和管理GPU device,掌握GPU信息查询很重要,因为这可以帮助你设置kernel的执行配置。

本博文将主要介绍下面两方面内容:

  • CUDA runtime API function
  • NVIDIA系统管理命令行

使用runtime API来查询GPU信息

你可以使用下面的function来查询所有关于GPU device 的信息:

cudaError_t cudaGetDeviceProperties(cudaDeviceProp *prop, int device);

GPU的信息放在cudaDeviceProp这个结构体中。

代码

cpp 复制代码
#include <cuda_runtime.h>#include <stdio.h>int main(int argc, char **argv) {      printf("%s Starting...\n", argv[0]);
    int deviceCount = 0;
    cudaError_t error_id = cudaGetDeviceCount(&deviceCount);
    if (error_id != cudaSuccess) {
        printf("cudaGetDeviceCount returned %d\n-> %s\n",
        (int)error_id, cudaGetErrorString(error_id));
        printf("Result = FAIL\n");
        exit(EXIT_FAILURE);
    }
    if (deviceCount == 0) {
        printf("There are no available device(s) that support CUDA\n");
    } else {
        printf("Detected %d CUDA Capable device(s)\n", deviceCount);
    }
    int dev, driverVersion = 0, runtimeVersion = 0;
    dev =0;
    cudaSetDevice(dev);
    cudaDeviceProp deviceProp;
    cudaGetDeviceProperties(&deviceProp, dev);
    printf("Device %d: \"%s\"\n", dev, deviceProp.name);
    cudaDriverGetVersion(&driverVersion);
    cudaRuntimeGetVersion(&runtimeVersion);
    printf(" CUDA Driver Version / Runtime Version %d.%d / %d.%d\n",driverVersion/1000, (driverVersion%100)/10,runtimeVersion/1000, (runtimeVersion%100)/10);
    printf(" CUDA Capability Major/Minor version number: %d.%d\n",deviceProp.major, deviceProp.minor);
    printf(" Total amount of global memory: %.2f MBytes (%llu bytes)\n",(float)deviceProp.totalGlobalMem/(pow(1024.0,3)),(unsigned long long) deviceProp.totalGlobalMem);
    printf(" GPU Clock rate: %.0f MHz (%0.2f GHz)\n",deviceProp.clockRate * 1e-3f, deviceProp.clockRate * 1e-6f);
    printf(" Memory Clock rate: %.0f Mhz\n",deviceProp.memoryClockRate * 1e-3f);
    printf(" Memory Bus Width: %d-bit\n",deviceProp.memoryBusWidth);
    if (deviceProp.l2CacheSize) {
        printf(" L2 Cache Size: %d bytes\n",
        deviceProp.l2CacheSize);
    }
    printf(" Max Texture Dimension Size (x,y,z) 1D=(%d), 2D=(%d,%d), 3D=(%d,%d,%d)\n",
    deviceProp.maxTexture1D , deviceProp.maxTexture2D[0],
    deviceProp.maxTexture2D[1],
    deviceProp.maxTexture3D[0], deviceProp.maxTexture3D[1],
    deviceProp.maxTexture3D[2]);
    printf(" Max Layered Texture Size (dim) x layers 1D=(%d) x %d, 2D=(%d,%d) x %d\n",
    deviceProp.maxTexture1DLayered[0], deviceProp.maxTexture1DLayered[1],
    deviceProp.maxTexture2DLayered[0], deviceProp.maxTexture2DLayered[1],
    deviceProp.maxTexture2DLayered[2]);
    printf(" Total amount of constant memory: %lu bytes\n",deviceProp.totalConstMem);
    printf(" Total amount of shared memory per block: %lu bytes\n",deviceProp.sharedMemPerBlock);
    printf(" Total number of registers available per block: %d\n",deviceProp.regsPerBlock);
    printf(" Warp size: %d\n", deviceProp.warpSize);
    printf(" Maximum number of threads per multiprocessor: %d\n",deviceProp.maxThreadsPerMultiProcessor);
    printf(" Maximum number of threads per block: %d\n",deviceProp.maxThreadsPerBlock);
    printf(" Maximum sizes of each dimension of a block: %d x %d x %d\n",
    deviceProp.maxThreadsDim[0],
    deviceProp.maxThreadsDim[1],
    deviceProp.maxThreadsDim[2]);
    printf(" Maximum sizes of each dimension of a grid: %d x %d x %d\n",
    deviceProp.maxGridSize[0],
    deviceProp.maxGridSize[1],
    deviceProp.maxGridSize[2]);
    printf(" Maximum memory pitch: %lu bytes\n", deviceProp.memPitch);
    exit(EXIT_SUCCESS);
}

编译运行:

复制代码
$ nvcc checkDeviceInfor.cu -o checkDeviceInfor
$ ./checkDeviceInfor

决定最佳GPU

对于支持多GPU的系统,是需要从中选择一个来作为我们的device的,抉择出最佳计算性能GPU的一种方法就是由其拥有的处理器数量决定,可以用下面的代码来选择最佳GPU。

cpp 复制代码
int numDevices = 0;
cudaGetDeviceCount(&numDevices);
if (numDevices > 1) {
    int maxMultiprocessors = 0, maxDevice = 0;
    for (int device=0; device<numDevices; device++) {
        cudaDeviceProp props;
        cudaGetDeviceProperties(&props, device);
        if (maxMultiprocessors < props.multiProcessorCount) {
            maxMultiprocessors = props.multiProcessorCount;
            maxDevice = device;
        }
    }
    cudaSetDevice(maxDevice);
}

使用nvidia-smi来查询GPU信息

nvidia-smi是一个命令行工具,可以帮助你管理操作GPU device,并且允许你查询和更改device状态。

nvidia-smi用处很多,比如,下面的指令:

复制代码
$ nvidia-smi -L
GPU 0: Tesla M2070 (UUID: GPU-68df8aec-e85c-9934-2b81-0c9e689a43a7)
GPU 1: Tesla M2070 (UUID: GPU-382f23c1-5160-01e2-3291-ff9628930b70)

然后可以使用下面的命令来查询GPU 0 的详细信息:

复制代码
$nvidia-smi –q –i 0

下面是该命令的一些参数,可以精简nvidia-smi的显示信息:

MEMORY

UTILIZATION

ECC

TEMPERATURE

POWER

CLOCK

COMPUTE

PIDS

PERFORMANCE

SUPPORTED_CLOCKS

PAGE_RETIREMENT

ACCOUNTING

比如,显示只device memory的信息:

复制代码
$nvidia-smi –q –i 0 –d    MEMORY | tail –n 5
Memory Usage
Total : 5375 MB
Used : 9 MB
Free : 5366 MB

设置device

对于多GPU系统,使用nvidia-smi可以查看各GPU属性,每个GPU从0开始依次标注,使用环境变量CUDA_VISIBLE_DEVICES可以指定GPU而不用修改application。

可以设置环境变量CUDA_VISIBLE_DEVICES-2来屏蔽其他GPU,这样只有GPU2能被使用。当然也可以使用CUDA_VISIBLE_DEVICES-2,3来设置多个GPU,他们的device ID分别为0和1.

相关推荐
Go Work1 小时前
docker 占满根分区时先分清谁在吃盘
经验分享·笔记
3095566662 小时前
股票接口返回 404 与空数组的排查笔记:证书状态与级别参数
java·笔记·python·ios·iphone·股票数据api·股票数据接口
蒸蒸yyyyzwd2 小时前
从邓明学习的后端笔记
笔记·学习
岑梓铭2 小时前
《考研408数据结构》第八章(排序)复习笔记
数据结构·笔记
机器学习之心2 小时前
基于变量相关图与残差学习的 GCN 多变量回归方法——混凝土 28 天抗压强度预测
学习·回归·gcn
Rabitebla15 小时前
【Linux】进程控制(十二) 自定义 Shell(二):内建命令与进程工作目录管理
linux·c++·笔记·学习·bash
Gary移动存储固件15 小时前
eMMC5.1协议中文学习讲解(6.6.17~6.6.22.4.6)
学习·ufs·emmc·nand·存储固件
一个天蝎座 白勺 程序猿16 小时前
别让收藏夹替你学习:我搭AI知识体系的完整方法,脚本直接拿去用
人工智能·学习·ai·ai学习
楚山之石17 小时前
【Nat Biomed Eng】Connectome 2.0 超高梯度扫描仪:500 mT/m 与 600 T/m/s 把活体人脑微观结构分辨推进到亚微米级
图像处理·学习·数据分析·mri
坤坤子吖19 小时前
Linux网络编程:TCP 粘包与半包问题,如何正确处理 TCP 流式数据?
linux·服务器·网络·笔记·网络协议·学习