Skip to main content

CUDA获取GPU的硬件信息

在GPU加速计算和深度学习应用中,了解GPU硬件参数对于性能优化和资源分配至关重要。不同的GPU型号具有不同的计算能力、内存配置和架构特性,这些因素直接影响应用程序的性能表现。本文将详细介绍如何通过CUDA编程获取GPU硬件信息,并解释各项参数的意义和应用场景。

1. 获取GPU硬件信息

1.1. 实现方案

获取GPU硬件信息,主要通过以下几个接口来实现。

  • cudaGetDeviceCount:获取当前系统中可用的GPU设备数量。
  • cudaGetDeviceProperties:获取指定GPU设备的基础信息,如设备名称、计算能力、全局内存大小等。
  • cudaDeviceGetAttribute:获取指定GPU设备的高级信息,如核心时钟频率、内存时钟频率。

1.2. 完整源代码

#include <cuda_runtime.h>
#include <iostream>
#include <iomanip>

void getDeviceBaseProperties(int deviceIdx) {
// 使用cudaGetDeviceProperties获取基础信息
cudaDeviceProp prop;
cudaGetDeviceProperties(&prop, deviceIdx);
std::cout << " --------------- GPU设备基础信息 ---------------" << std::endl;
std::cout << " 设备名称: " << prop.name << std::endl;
std::cout << " 计算能力: " << prop.major << "." << prop.minor << std::endl;
std::cout << " 全局内存(显存): " << prop.totalGlobalMem / (1024 * 1024 * 1024.0) << " GB" << std::endl;
std::cout << " 流多处理器(SM)数量: " << prop.multiProcessorCount << std::endl;
std::cout << " 线程束大小: " << prop.warpSize << std::endl;
std::cout << " 每个块的最大线程数: " << prop.maxThreadsPerBlock << std::endl;
std::cout << " 每个块的共享内存: " << prop.sharedMemPerBlock / 1024 << " KB" << std::endl;
std::cout << " L2缓存大小: " << prop.l2CacheSize / 1024 << " KB" << std::endl;
std::cout << " 内存总线宽度: " << prop.memoryBusWidth << " bit" << std::endl;
std::cout << " ECC支持: " << (prop.ECCEnabled ? "是" : "否") << std::endl;
std::cout << " 统一地址空间: " << (prop.unifiedAddressing ? "是" : "否") << std::endl;
std::cout << " 托管内存支持: " << (prop.managedMemory ? "是" : "否") << std::endl;
std::cout << " 并发内核执行: " << (prop.concurrentKernels ? "是" : "否") << std::endl;
}

void getDeviceAdvancedProperties(int deviceIdx)
{
// 使用cudaDeviceGetAttribute获取高级信息
std::cout << " --------------- GPU设备高级信息 ---------------" << std::endl;

int attrValue;
cudaDeviceGetAttribute(&attrValue, cudaDevAttrClockRate, deviceIdx);
std::cout << " 核心时钟频率: " << attrValue / 1000 << " MHz" << std::endl;
cudaDeviceGetAttribute(&attrValue, cudaDevAttrMemoryClockRate, deviceIdx);
std::cout << " 内存时钟频率: " << attrValue / 1000 << " MHz" << std::endl;
cudaDeviceGetAttribute(&attrValue, cudaDevAttrGlobalMemoryBusWidth, deviceIdx);
std::cout << " 内存总线宽度: " << attrValue << " bits" << std::endl;
}

int main() {
// 获取GPU设备数量
int deviceCount;
cudaGetDeviceCount(&deviceCount);
if (deviceCount == 0) {
std::cout << "未找到可用的CUDA设备" << std::endl;
return 0;
}

for (int deviceIdx = 0; deviceIdx < deviceCount; deviceIdx++) {
std::cout << "【设备 " << deviceIdx << "】:" << std::endl;
// 基础信息
getDeviceBaseProperties(deviceIdx);
// 高级信息
getDeviceAdvancedProperties(deviceIdx);
}

return 0;
}

1.3. 编译和运行

# 编译
nvcc ./get_device_info.cu

# 运行
./a.out
【设备 0】:
--------------- GPU设备基础信息 ---------------
设备名称: NVIDIA GeForce RTX 3060
计算能力: 8.6
全局内存(显存): 11.9994 GB
流多处理器(SM)数量: 28
线程束大小: 32
每个块的最大线程数: 1024
每个块的共享内存: 48 KB
L2缓存大小: 2304 KB
内存总线宽度: 192 bit
ECC支持: 否
统一地址空间: 是
托管内存支持: 是
并发内核执行: 是
--------------- GPU设备高级信息 ---------------
核心时钟频率: 1777 MHz
内存时钟频率: 7501 MHz
内存总线宽度: 192 bits

1.4. cudaGetDeviceProperties与cudaDeviceGetAttribute的区别

在CUDA编程中,cudaGetDevicePropertiescudaDeviceGetAttribute都是用于获取GPU设备信息的重要函数,但它们在使用方式、功能和适用场景上有显著区别。

1.4.1. 函数原型

cudaGetDeviceProperties:

cudaError_t cudaGetDeviceProperties(cudaDeviceProp* prop, int device);
  • 一次性获取设备的所有属性
  • 返回完整的cudaDeviceProp结构体

cudaDeviceGetAttribute:

cudaError_t cudaDeviceGetAttribute(int* value, cudaDeviceAttr attr, int device);
  • 获取设备的单个特定属性
  • 需要指定要查询的属性枚举值

1.4.2. 核心区别

特性cudaGetDevicePropertiescudaDeviceGetAttribute
核心功能一次性获取设备的所有属性获取设备的单个特定属性
类型支持支持多种不同的数据类型,如char[]字符串、int整数、int数组等只能返回int类型的属性值
内存开销较大(整个结构体)很小(单个整数)
兼容性较差,有些新的属性值不支持较好
使用场景1. 在程序初始化时一次性获取所有需要的设备信息
2. 获取基础设备信息
1. 程序运行时查询特定设备属性
2. 获取设备的高级(新增的)属性

1.4.3. 相互关系

cudaGetDeviceProperties 和 cudaDeviceGetAttribute 获取的设备属性有重叠的部分,也有不同的部分

  • 重叠的部分: 如cudaDevAttrGlobalMemoryBusWidth对应cudaDeviceProp的memoryBusWidth,更多的属性对应关系参见2.2小节:cudaDeviceAttr枚举详解
  • 不同的部分:
    • 如cudaGetDeviceProperties可以获取设备型号,cudaDeviceGetAttribute不支持。
    • cudaDeviceGetAttribute新增的属性,cudaDeviceProp可能不支持。

2. 常见硬件参数的含义和功能

2.1. cudaDeviceProp结构体字段详解

cudaDeviceProp结构体是CUDA编程中获取GPU硬件信息的关键数据结构,它包含了设备的完整属性信息。下面我将详细解释每个字段的含义及其对应的硬件参数功能。

2.1.1. 基本设备信息

char name[256]
  • 含义:设备名称的ASCII字符串标识
  • 硬件参数:GPU型号名称(如"NVIDIA GeForce RTX 4090")
  • 功能:识别具体的GPU型号和制造商
  • 应用场景:设备选择、日志记录、性能报告
cudaUUID_t uuid
  • 含义:16字节的唯一设备标识符
  • 硬件参数:设备的全局唯一ID
  • 功能:在多GPU系统中唯一标识每个设备
  • 应用场景:设备持久性识别、多GPU系统管理
size_t totalGlobalMem
  • 含义:设备全局内存总大小(字节)
  • 硬件参数:GPU显存容量
  • 功能:存储需要处理的数据和中间结果
  • 应用场景:内存分配决策、数据分块策略

2.1.2. 计算架构相关参数

int majorint minor
  • 含义:主次计算能力版本号
  • 硬件参数:GPU架构世代(如8.0代表Ampere架构)
  • 功能:确定支持的CUDA功能和指令集
  • 应用场景:功能兼容性检查、代码路径选择
int warpSize
  • 含义:线程束大小(线程数)
  • 硬件参数:SIMD宽度,通常为32
  • 功能:GPU调度和执行的基本单位
  • 应用场景:线程组织优化、分支 divergence 避免
int multiProcessorCount
  • 含义:流多处理器(SM)数量
  • 硬件参数:GPU中的计算单元数量
  • 功能:决定并行计算能力
  • 应用场景:性能估算、工作负载分配

2.1.3. 内存系统参数

size_t sharedMemPerBlock
  • 含义:每个线程块可用的共享内存大小(字节)
  • 硬件参数:每个SM上的高速可编程缓存
  • 功能:线程块内线程间数据共享和通信
  • 应用场景:数据重用优化、矩阵乘法、卷积运算
size_t sharedMemPerMultiprocessor
  • 含义:每个多处理器的共享内存大小(字节)
  • 硬件参数:SM上的共享内存总量
  • 功能:限制同时驻留的线程块数量
  • 应用场景:资源分配优化
size_t totalConstMem
  • 含义:设备常量内存总大小(字节)
  • 硬件参数:只读缓存内存
  • 功能:存储只读数据,提供高速访问
  • 应用场景:存储常数参数、查询表
int l2CacheSize
  • 含义:L2缓存大小(字节)
  • 硬件参数:全局共享缓存
  • 功能:减少全局内存访问延迟
  • 应用场景:内存访问模式优化
int memoryBusWidth
  • 含义:全局内存总线宽度(位)
  • 硬件参数:内存接口宽度
  • 功能:决定内存带宽的理论上限
  • 应用场景:带宽计算、性能瓶颈分析

2.1.4. 线程和块配置参数

int maxThreadsPerBlock
  • 含义:每个块的最大线程数
  • 硬件参数:单个线程块的大小限制
  • 功能:限制线程块的规模
  • 应用场景:线程块大小优化
int maxThreadsDim[3]
  • 含义:每个维度线程数的最大值 [x, y, z]
  • 硬件参数:线程块维度的硬件限制
  • 功能:定义线程块的最大形状
  • 应用场景:多维线程组织
int maxGridSize[3]
  • 含义:每个维度网格大小的最大值 [x, y, z]
  • 硬件参数:网格维度的硬件限制
  • 功能:定义网格的最大规模
  • 应用场景:大规模并行计算
int maxThreadsPerMultiProcessor
  • 含义:每个多处理器的最大驻留线程数
  • 硬件参数:SM的线程容量
  • 功能:限制SM上同时执行的线程数量
  • 应用场景: occupancy 计算
int maxBlocksPerMultiProcessor
  • 含义:每个多处理器的最大驻留块数
  • 硬件参数:SM的块容量
  • 功能:限制SM上同时驻留的线程块数量
  • 应用场景: occupancy 优化

2.1.5. 寄存器资源

int regsPerBlock
  • 含义:每个块可用的32位寄存器数量
  • 硬件参数:每个线程块的寄存器资源
  • 功能:存储线程局部变量,提供最快访问速度
  • 应用场景:寄存器使用优化
int regsPerMultiprocessor
  • 含义:每个多处理器的32位寄存器总数
  • 硬件参数:SM的寄存器总容量
  • 功能:限制SM上所有线程的寄存器使用总量
  • 应用场景:资源分配规划

2.1.6. 纹理和表面内存

各种 maxTexture*maxSurface* 字段
  • 含义:各种纹理和表面内存的最大尺寸限制
  • 硬件参数:纹理和表面内存单元的硬件限制
  • 功能:定义可用的纹理和表面内存资源
  • 应用场景:图形处理、图像处理、特殊内存访问模式

2.1.7. 特性支持标志

int unifiedAddressing
  • 含义:设备支持统一地址空间
  • 硬件参数:UVA(Unified Virtual Addressing)支持
  • 功能:CPU和GPU共享统一的地址空间
  • 应用场景:简化内存管理、零拷贝内存
int managedMemory
  • 含义:设备支持托管内存
  • 硬件参数:UM(Unified Memory)支持
  • 功能:自动内存迁移和一致性管理
  • 应用场景:简化编程模型、处理大数据集
int concurrentKernels
  • 含义:设备支持并发内核执行
  • 硬件参数:多个内核同时执行能力
  • 功能:提高GPU利用率
  • 应用场景:流水线执行、多任务处理
int ECCEnabled
  • 含义:ECC内存支持是否启用
  • 硬件参数:错误检查和纠正功能状态
  • 功能:提高内存可靠性
  • 应用场景:科学计算、关键任务应用

2.1.8. PCIe和系统集成

int pciBusID, pciDeviceID, pciDomainID
  • 含义:PCI总线信息
  • 硬件参数:设备在PCI总线中的位置
  • 功能:设备识别和选择
  • 应用场景:多GPU系统管理、PCIe拓扑分析
int integrated
  • 含义:设备是否为集成GPU
  • 硬件参数:GPU集成方式
  • 功能:区分集成和独立GPU
  • 应用场景:功耗管理、性能预期

2.1.9. 高级功能支持

int cooperativeLaunch
  • 含义:支持协作组启动
  • 硬件参数:网格同步功能支持
  • 功能:实现网格级别的同步和通信
  • 应用场景:复杂并行算法
int streamPrioritiesSupported
  • 含义:支持流优先级
  • 硬件参数:流调度优先级支持
  • 功能:控制内核执行顺序
  • 应用场景:实时调度、QoS管理

2.2. cudaDeviceAttr枚举详解

cudaDeviceAttr枚举提供了通过cudaDeviceGetAttribute函数查询设备属性的标准化方式。下面我将详细解释每个枚举值的含义、功能及其与cudaDeviceProp结构体的对应关系。

2.2.1. 基本计算能力参数

枚举值含义对应cudaDeviceProp字段功能描述
cudaDevAttrComputeCapabilityMajor主计算能力版本majorGPU架构的主版本号
cudaDevAttrComputeCapabilityMinor次计算能力版本minorGPU架构的次版本号
cudaDevAttrWarpSize线程束大小warpSizeSIMD宽度,通常为32线程

2.2.2. 线程和块配置限制

枚举值含义对应cudaDeviceProp字段功能描述
cudaDevAttrMaxThreadsPerBlock每块最大线程数maxThreadsPerBlock单个线程块的最大线程数量
cudaDevAttrMaxBlockDimX块维度X最大值maxThreadsDim[0]线程块X维度的最大大小
cudaDevAttrMaxBlockDimY块维度Y最大值maxThreadsDim[1]线程块Y维度的最大大小
cudaDevAttrMaxBlockDimZ块维度Z最大值maxThreadsDim[2]线程块Z维度的最大大小
cudaDevAttrMaxGridDimX网格维度X最大值maxGridSize[0]网格X维度的最大大小
cudaDevAttrMaxGridDimY网格维度Y最大值maxGridSize[1]网格Y维度的最大大小
cudaDevAttrMaxGridDimZ网格维度Z最大值maxGridSize[2]网格Z维度的最大大小

2.2.3. 内存系统参数

枚举值含义对应cudaDeviceProp字段功能描述
cudaDevAttrMaxSharedMemoryPerBlock每块共享内存sharedMemPerBlock每个线程块可用的共享内存大小
cudaDevAttrTotalConstantMemory常量内存总量totalConstMem设备常量内存总大小
cudaDevAttrMaxSharedMemoryPerMultiprocessor每SM共享内存sharedMemPerMultiprocessor每个多处理器的共享内存总量
cudaDevAttrMaxRegistersPerBlock每块寄存器数regsPerBlock每个线程块可用的寄存器数量
cudaDevAttrMaxRegistersPerMultiprocessor每SM寄存器数regsPerMultiprocessor每个多处理器的寄存器总量
cudaDevAttrL2CacheSizeL2缓存大小l2CacheSizeL2缓存容量(字节)
cudaDevAttrGlobalMemoryBusWidth内存总线宽度memoryBusWidth全局内存总线宽度(位)

2.2.4. 时钟和性能参数

枚举值含义对应cudaDeviceProp字段功能描述
cudaDevAttrClockRate核心时钟频率无直接对应GPU核心时钟频率(kHz)
cudaDevAttrMemoryClockRate内存时钟频率无直接对应内存时钟频率(kHz)
cudaDevAttrSingleToDoublePrecisionPerfRatio单双精度性能比单精度与双精度浮点性能比率

2.2.5. 多处理器相关参数

枚举值含义对应cudaDeviceProp字段功能描述
cudaDevAttrMultiProcessorCount多处理器数量multiProcessorCount流多处理器(SM)的数量
cudaDevAttrMaxThreadsPerMultiProcessor每SM最大线程数maxThreadsPerMultiProcessor每个SM支持的最大线程数
cudaDevAttrMaxBlocksPerMultiprocessor每SM最大块数maxBlocksPerMultiProcessor每个SM支持的最大块数

2.2.6. 纹理和表面内存限制

纹理维度限制:

  • cudaDevAttrMaxTexture1DWidth - 最大1D纹理宽度
  • cudaDevAttrMaxTexture2DWidth - 最大2D纹理宽度
  • cudaDevAttrMaxTexture2DHeight - 最大2D纹理高度
  • cudaDevAttrMaxTexture3DWidth - 最大3D纹理宽度
  • 等等(对应cudaDeviceProp中的各种maxTexture*字段)

表面内存限制:

  • cudaDevAttrMaxSurface1DWidth - 最大1D表面宽度
  • cudaDevAttrMaxSurface2DWidth - 最大2D表面宽度
  • 等等(对应cudaDeviceProp中的各种maxSurface*字段)

2.2.7. 特性支持标志

枚举值含义对应cudaDeviceProp字段功能描述
cudaDevAttrConcurrentKernels并发内核支持concurrentKernels是否支持并发内核执行
cudaDevAttrEccEnabledECC支持状态ECCEnabledECC内存是否启用
cudaDevAttrUnifiedAddressing统一寻址支持unifiedAddressing是否支持统一地址空间
cudaDevAttrManagedMemory托管内存支持managedMemory是否支持托管内存
cudaDevAttrComputePreemptionSupported计算抢占支持computePreemptionSupported是否支持计算抢占
cudaDevAttrCooperativeLaunch协作启动支持cooperativeLaunch是否支持协作内核启动

2.2.8. PCIe和系统集成

枚举值含义对应cudaDeviceProp字段功能描述
cudaDevAttrPciBusIdPCI总线IDpciBusIDPCI总线标识符
cudaDevAttrPciDeviceIdPCI设备IDpciDeviceIDPCI设备标识符
cudaDevAttrPciDomainIdPCI域IDpciDomainIDPCI域标识符
cudaDevAttrIntegrated集成GPU标志integrated是否为集成GPU

2.2.9. 高级功能支持

枚举值含义功能描述
cudaDevAttrStreamPrioritiesSupported流优先级支持是否支持流优先级
cudaDevAttrGlobalL1CacheSupported全局L1缓存支持是否支持在L1中缓存全局变量
cudaDevAttrLocalL1CacheSupported局部L1缓存支持是否支持在L1中缓存局部变量
cudaDevAttrPageableMemoryAccess可分页内存访问是否支持直接访问可分页内存

2.2.10. 现代特性支持(较新架构)

枚举值含义功能描述
cudaDevAttrMemoryPoolsSupported内存池支持是否支持异步内存分配API
cudaDevAttrGPUDirectRDMASupportedGPUDirect RDMA支持是否支持GPUDirect RDMA
cudaDevAttrClusterLaunch集群启动支持是否支持集群启动
cudaDevAttrNumaConfigNUMA配置NUMA配置信息
cudaDevAttrNumaIdNUMA节点IDGPU内存的NUMA节点ID