From cbd7865a793a40d3f379a08b50498141568fa395 Mon Sep 17 00:00:00 2001 From: Tanguy Pruvot Date: Wed, 27 May 2015 17:11:56 +0200 Subject: [PATCH] nvml: check supported graphics clocks... and use reset application clocks api --- nvml.cpp | 32 ++++++++++++++++++++------------ nvml.h | 2 ++ 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/nvml.cpp b/nvml.cpp index 6fb2358..3f629e9 100644 --- a/nvml.cpp +++ b/nvml.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include "miner.h" #include "nvml.h" @@ -132,6 +133,10 @@ nvml_handle * nvml_create() wrap_dlsym(nvmlh->nvml_dll, "nvmlDeviceGetApplicationsClock"); nvmlh->nvmlDeviceSetApplicationsClocks = (nvmlReturn_t (*)(nvmlDevice_t, unsigned int mem, unsigned int gpu)) wrap_dlsym(nvmlh->nvml_dll, "nvmlDeviceSetApplicationsClocks"); + nvmlh->nvmlDeviceResetApplicationsClocks = (nvmlReturn_t (*)(nvmlDevice_t)) + wrap_dlsym(nvmlh->nvml_dll, "nvmlDeviceResetApplicationsClocks"); + nvmlh->nvmlDeviceGetSupportedGraphicsClocks = (nvmlReturn_t (*)(nvmlDevice_t, uint32_t mem, uint32_t *num, uint32_t *)) + wrap_dlsym(nvmlh->nvml_dll, "nvmlDeviceGetSupportedGraphicsClocks"); nvmlh->nvmlDeviceGetClockInfo = (nvmlReturn_t (*)(nvmlDevice_t, nvmlClockType_t, unsigned int *clock)) wrap_dlsym(nvmlh->nvml_dll, "nvmlDeviceGetClockInfo"); nvmlh->nvmlDeviceGetPciInfo = (nvmlReturn_t (*)(nvmlDevice_t, nvmlPciInfo_t *)) @@ -290,6 +295,18 @@ int nvml_set_clocks(nvml_handle *nvmlh, int dev_id) if (device_mem_clocks[c]) mem_clk = device_mem_clocks[c]; if (device_gpu_clocks[c]) gpu_clk = device_gpu_clocks[c]; + uint32_t nclocks, clocks[128] = { 0 }; + nvmlh->nvmlDeviceGetSupportedGraphicsClocks(nvmlh->devs[n], mem_clk, &nclocks, NULL); + nclocks = min(nclocks, 128); + nvmlh->nvmlDeviceGetSupportedGraphicsClocks(nvmlh->devs[n], mem_clk, &nclocks, clocks); + for (unsigned int u=0; u < nclocks; u++) { + // ordered desc, so get first + if (clocks[u] <= device_gpu_clocks[c]) { + gpu_clk = clocks[u]; + break; + } + } + rc = nvmlh->nvmlDeviceSetApplicationsClocks(nvmlh->devs[n], mem_clk, gpu_clk); if (rc == NVML_SUCCESS) applog(LOG_INFO, "GPU #%d: application clocks set to %u/%u", c, mem_clk, gpu_clk); @@ -315,21 +332,12 @@ int nvml_reset_clocks(nvml_handle *nvmlh, int dev_id) return 0; // nothing to do int c = nvmlh->nvml_cuda_device_id[n]; - nvmlh->nvmlDeviceGetDefaultApplicationsClock(nvmlh->devs[n], NVML_CLOCK_MEM, &mem_clk); - rc = nvmlh->nvmlDeviceGetDefaultApplicationsClock(nvmlh->devs[n], NVML_CLOCK_GRAPHICS, &gpu_clk); - if (rc != NVML_SUCCESS) { - applog(LOG_WARNING, "GPU #%d: unable to query application clocks", c); - return -1; - } - rc = nvmlh->nvmlDeviceSetApplicationsClocks(nvmlh->devs[n], mem_clk, gpu_clk); - if (rc == NVML_SUCCESS) - applog(LOG_INFO, "GPU #%d: application clocks reset to %u/%u", c, mem_clk, gpu_clk); - else { - applog(LOG_ERR, "GPU #%d: %u/%u - %s", c, mem_clk, gpu_clk, nvmlh->nvmlErrorString(rc)); + rc = nvmlh->nvmlDeviceResetApplicationsClocks(nvmlh->devs[n]); + if (rc != NVML_SUCCESS) { + applog(LOG_WARNING, "GPU #%d: unable to reset application clocks", c); return -1; } - gpu_clocks_changed[dev_id] = 0; } diff --git a/nvml.h b/nvml.h index e23a069..a7f9260 100644 --- a/nvml.h +++ b/nvml.h @@ -94,6 +94,8 @@ typedef struct { nvmlReturn_t (*nvmlDeviceGetDefaultApplicationsClock)(nvmlDevice_t, nvmlClockType_t, unsigned int *); nvmlReturn_t (*nvmlDeviceGetApplicationsClock)(nvmlDevice_t, nvmlClockType_t, unsigned int *); nvmlReturn_t (*nvmlDeviceSetApplicationsClocks)(nvmlDevice_t, unsigned int, unsigned int); + nvmlReturn_t (*nvmlDeviceResetApplicationsClocks)(nvmlDevice_t); + nvmlReturn_t (*nvmlDeviceGetSupportedGraphicsClocks)(nvmlDevice_t, uint32_t mem, uint32_t *num, uint32_t *arr); nvmlReturn_t (*nvmlDeviceGetClockInfo)(nvmlDevice_t, nvmlClockType_t, unsigned int *); nvmlReturn_t (*nvmlDeviceGetPciInfo)(nvmlDevice_t, nvmlPciInfo_t *); nvmlReturn_t (*nvmlDeviceGetName)(nvmlDevice_t, char *, int);