diff --git a/src/detection/gpu/gpu_driver_specific.h b/src/detection/gpu/gpu_driver_specific.h index 8c935ff8c..c22ce18eb 100644 --- a/src/detection/gpu/gpu_driver_specific.h +++ b/src/detection/gpu/gpu_driver_specific.h @@ -42,6 +42,7 @@ typedef struct FFGpuDriverResult uint32_t* coreCount; FFGPUType* type; uint32_t* frequency; + uint8_t* usage; } FFGpuDriverResult; const char* ffDetectNvidiaGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverResult result, const char* soName); diff --git a/src/detection/gpu/gpu_nvidia.c b/src/detection/gpu/gpu_nvidia.c index 683e681ef..5d158833a 100644 --- a/src/detection/gpu/gpu_nvidia.c +++ b/src/detection/gpu/gpu_nvidia.c @@ -12,6 +12,7 @@ struct FFNvmlData { FF_LIBRARY_SYMBOL(nvmlDeviceGetMemoryInfo_v2) FF_LIBRARY_SYMBOL(nvmlDeviceGetNumGpuCores) FF_LIBRARY_SYMBOL(nvmlDeviceGetMaxClockInfo) + FF_LIBRARY_SYMBOL(nvmlDeviceGetUtilizationRates) FF_LIBRARY_SYMBOL(nvmlDeviceGetBrand) bool inited; @@ -35,6 +36,7 @@ const char* ffDetectNvidiaGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverR FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetMemoryInfo_v2) FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetNumGpuCores) FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetMaxClockInfo) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetUtilizationRates) FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libnvml, nvmlData, nvmlDeviceGetBrand) if (ffnvmlInit_v2() != NVML_SUCCESS) @@ -124,6 +126,13 @@ const char* ffDetectNvidiaGpuInfo(const FFGpuDriverCondition* cond, FFGpuDriverR if (result.frequency) nvmlData.ffnvmlDeviceGetMaxClockInfo(device, NVML_CLOCK_GRAPHICS, result.frequency); + if (result.usage) + { + nvmlUtilization_t rates; + if (nvmlData.ffnvmlDeviceGetUtilizationRates(device, &rates) == NVML_SUCCESS) + *result.usage = (uint8_t) rates.gpu; + } + return NULL; #else diff --git a/src/detection/gpu/nvml.h b/src/detection/gpu/nvml.h index ea776a4be..d3f1904b0 100644 --- a/src/detection/gpu/nvml.h +++ b/src/detection/gpu/nvml.h @@ -94,6 +94,16 @@ typedef enum { NVML_BRAND_COUNT, } nvmlBrandType_t; +// https://docs.nvidia.com/deploy/nvml-api/structnvmlUtilization__t.html#structnvmlUtilization__t +// Utilization information for a device. +typedef struct +{ + // Percent of time over the past second during which one or more kernels was executing on the GPU + unsigned int gpu; + // Percent of time over the past second during which global (device) memory was being read or written + unsigned int memory; +} nvmlUtilization_t; + // https://docs.nvidia.com/deploy/nvml-api/group__nvmlInitializationAndCleanup.html#group__nvmlInitializationAndCleanup // Initialize NVML, but don't initialize any GPUs yet nvmlReturn_t nvmlInit_v2(void); @@ -119,3 +129,5 @@ extern nvmlReturn_t nvmlDeviceGetNumGpuCores(nvmlDevice_t device, unsigned int* extern nvmlReturn_t nvmlDeviceGetMaxClockInfo(nvmlDevice_t device, nvmlClockType_t type, unsigned int* clock); // Retrieves the brand of this device extern nvmlReturn_t nvmlDeviceGetBrand(nvmlDevice_t device, nvmlBrandType_t* type); +// Retrieves the current utilization rates for the device +extern nvmlReturn_t nvmlDeviceGetUtilizationRates(nvmlDevice_t device, nvmlUtilization_t *utilization);