使用什么库或者SDK可以获取amd的GPU使用率和GPU内存使用率信息,使用C++代码
时间: 2024-05-10 12:13:45 浏览: 263
您可以使用AMD的ROCm SDK提供的API获取AMD GPU的使用率和内存使用率信息。具体来说,您可以使用Power Profiling API获取GPU使用率,使用Performance Counter API获取GPU内存使用率。
下面是使用C代码获取AMD GPU使用率和内存使用率的示例:
获取GPU使用率:
```
#include <roctracer_ext.h>
void get_gpu_usage(int device_id) {
uint32_t domain = ACTIVITY_DOMAIN_HSA_AMD_GPU_ID; // activity domain for AMD GPU
roctracer_properties_t props;
memset(&props, 0, sizeof(roctracer_properties_t));
props.buffer_size = 1024;
props.buffer_callback_fun = [](uint32_t cid, const void* buffer, size_t size, uint32_t source_id) {
roctracer_record_t* record = (roctracer_record_t*)buffer;
for (int i = 0; i < size / sizeof(roctracer_record_t); i++) {
if (record[i].domain == ACTIVITY_DOMAIN_HSA_AMD_GPU_ID && record[i].kind == ACTIVITY_KIND_HSA_AMD_GPUPROFILE) {
roctracer_activity_hsa_amd_gpu_profile_t* prof = (roctracer_activity_hsa_amd_gpu_profile_t*)(record[i].payload);
if (prof->dev_index == device_id) {
printf("GPU usage: %.2f%%\n", (float)prof->data.curutil / 100.0f);
}
}
}
};
roctracer_enable_callback_ex(1, &domain, 1, &props);
// do something to trigger GPU activities
roctracer_disable_callback_ex();
}
```
其中,`device_id`参数是AMD GPU的设备ID,可以通过AMD的ROCm API获取。函数中使用了`roctracer`库提供的回调函数机制,监听AMD GPU的`ACTIVITY_KIND_HSA_AMD_GPUPROFILE`事件并解析其payload,从而获取GPU使用率信息。
获取GPU内存使用率:
```
#include <hsa.h>
#include <hsa_ext_amd.h>
void get_gpu_mem_usage(int device_id) {
hsa_amd_memory_pool_t* pool;
hsa_amd_memory_pool_global_flag_t flags = (hsa_amd_memory_pool_global_flag_t)(
HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_FINE_GRAINED |
HSA_AMD_MEMORY_POOL_GLOBAL_FLAG_COARSE_GRAINED);
hsa_amd_agent_memory_pool_get_info_fn_t mem_pool_info_fn = nullptr;
hsa_amd_agent_memory_pool_get_info_fn_t* mem_pool_info_fn_ptr = &mem_pool_info_fn;
hsa_agent_t agent;
hsa_status_t status;
status = hsa_iterate_agents([](hsa_agent_t agent, void* data) -> hsa_status_t {
hsa_device_type_t device_type;
hsa_status_t status = hsa_agent_get_info(agent, HSA_AGENT_INFO_DEVICE, &device_type);
if (status == HSA_STATUS_SUCCESS && device_type == HSA_DEVICE_TYPE_GPU) {
hsa_agent_t* gpu_agent = reinterpret_cast<hsa_agent_t*>(data);
*gpu_agent = agent;
return HSA_STATUS_INFO_BREAK;
}
return HSA_STATUS_SUCCESS;
}, &agent);
status = hsa_amd_agent_memory_pool_get_info(agent, HSA_AMD_AGENT_MEMORY_POOL_INFO_NUM, &mem_pool_info_fn_ptr);
uint32_t num_pools = mem_pool_info_fn(agent, HSA_AMD_AGENT_MEMORY_POOL_INFO_NUM);
for (int i = 0; i < num_pools; i++) {
pool = reinterpret_cast<hsa_amd_memory_pool_t*>(mem_pool_info_fn(agent, HSA_AMD_AGENT_MEMORY_POOL_INFO_PTR + i));
hsa_amd_memory_pool_global_flag_t pool_flags;
status = hsa_amd_memory_pool_get_info(*pool, HSA_AMD_MEMORY_POOL_INFO_GLOBAL_FLAGS, &pool_flags);
if ((flags & pool_flags) == flags) { // fine-grained + coarse-grained
hsa_amd_memory_pool_info_t info;
hsa_amd_memory_pool_get_info(*pool, HSA_AMD_MEMORY_POOL_INFO_ACCESSIBLE_BY_ALL, &info);
if (info == false) { // if the pool is not accessible by all agents, skip it
continue;
}
hsa_amd_memory_pool_statistics_t stats;
hsa_amd_memory_pool_get_info(*pool, HSA_AMD_MEMORY_POOL_INFO_STATISTICS, &stats);
if (stats.size == 0) { // if the pool has no memory usage statistics, skip it
continue;
}
hsa_amd_memory_pool_usage_t* usages = new hsa_amd_memory_pool_usage_t[stats.size];
hsa_amd_memory_pool_get_info(*pool, HSA_AMD_MEMORY_POOL_INFO_USAGE, usages);
for (int j = 0; j < stats.size; j++) {
if (usages[j].agent == agent && usages[j].size > 0) { // the memory usage of GPU
printf("GPU memory usage: %.2f%%\n", (float)usages[j].size * 100.0f / stats.max_size);
}
}
delete[] usages;
}
}
}
```
函数中使用了AMD的HSA API获取AMD GPU的内存池信息,然后从中筛选出可用的内存池,并获取其内存使用率信息。其中,`device_id`参数无用,因为HSA API只会获取当前运行的GPU的信息。函数中需要额外注意内存池是否可被所有Agent访问的问题。
以上代码仅供参考,具体实现方式可能会因环境和需求不同而有所差异。
阅读全文