From 4da35e0bcfcc5688d0484e379341b9c6ca580cfb Mon Sep 17 00:00:00 2001 From: Tanguy Pruvot Date: Mon, 6 Feb 2017 06:09:39 +0100 Subject: [PATCH] api: use MHz for all clocks and show plimit plimit value is reported in mW like the power, or % on Windows x86 (via nvapi) + the monitor thread will no more report 0W if the device doesnt support it also upgrade nvml and sample php api. some more changes may come in this temporary API 1.9 (for the final 2.0) --- api.cpp | 25 ++++++++++++++++-------- api/index.php | 19 +++++++++++++++--- miner.h | 2 ++ nvml.cpp | 54 ++++++++++++++++++++++++++++++++++++++++----------- nvml.h | 1 + util.cpp | 1 - 6 files changed, 79 insertions(+), 23 deletions(-) diff --git a/api.cpp b/api.cpp index c209b4e..6a29c42 100644 --- a/api.cpp +++ b/api.cpp @@ -118,6 +118,8 @@ static void gpustatus(int thr_id) char* card; cuda_gpu_info(cgpu); + cgpu->gpu_plimit = device_plimit[cgpu->gpu_id]; + #ifdef USE_WRAPNVML cgpu->has_monitoring = true; cgpu->gpu_bus = gpu_busid(cgpu); @@ -125,6 +127,7 @@ static void gpustatus(int thr_id) cgpu->gpu_fan = (uint16_t) gpu_fanpercent(cgpu); cgpu->gpu_fan_rpm = (uint16_t) gpu_fanrpm(cgpu); cgpu->gpu_power = gpu_power(cgpu); // mWatts + cgpu->gpu_plimit = gpu_plimit(cgpu); // mW or % #endif // todo: per gpu @@ -143,13 +146,14 @@ static void gpustatus(int thr_id) snprintf(buf, sizeof(buf), "GPU=%d;BUS=%hd;CARD=%s;TEMP=%.1f;" "POWER=%u;FAN=%hu;RPM=%hu;" - "FREQ=%u;CORE=%u;MEM=%u;" - "KHS=%.2f;KHW=%.5f;" + "FREQ=%u;MEMFREQ=%u;GPUF=%u;MEMF=%u;" + "KHS=%.2f;KHW=%.5f;PLIM=%u;" "HWF=%d;I=%.1f;THR=%u|", gpuid, cgpu->gpu_bus, card, cgpu->gpu_temp, cgpu->gpu_power, cgpu->gpu_fan, cgpu->gpu_fan_rpm, - cgpu->gpu_clock, cgpu->monitor.gpu_clock, cgpu->monitor.gpu_memclock, - cgpu->khashes, khashes_per_watt, + cgpu->gpu_clock/1000, cgpu->gpu_memclock/1000, // base freqs in MHz + cgpu->monitor.gpu_clock, cgpu->monitor.gpu_memclock, // current + cgpu->khashes, khashes_per_watt, cgpu->gpu_plimit, cgpu->hw_errors, cgpu->intensity, cgpu->throughput); // append to buffer for multi gpus @@ -266,6 +270,8 @@ static void gpuhwinfos(int gpu_id) return; cuda_gpu_info(cgpu); + cgpu->gpu_plimit = device_plimit[cgpu->gpu_id]; + #ifdef USE_WRAPNVML cgpu->has_monitoring = true; cgpu->gpu_bus = gpu_busid(cgpu); @@ -274,6 +280,7 @@ static void gpuhwinfos(int gpu_id) cgpu->gpu_fan_rpm = (uint16_t) gpu_fanrpm(cgpu); cgpu->gpu_pstate = (int16_t) gpu_pstate(cgpu); cgpu->gpu_power = gpu_power(cgpu); + cgpu->gpu_plimit = gpu_plimit(cgpu); gpu_info(cgpu); #ifdef WIN32 if (opt_debug) nvapi_pstateinfo(cgpu->gpu_id); @@ -287,12 +294,14 @@ static void gpuhwinfos(int gpu_id) card = device_name[gpu_id]; snprintf(buf, sizeof(buf), "GPU=%d;BUS=%hd;CARD=%s;SM=%hu;MEM=%u;" - "TEMP=%.1f;FAN=%hu;RPM=%hu;FREQ=%d;MEMFREQ=%d;PST=%s;POWER=%u;" + "TEMP=%.1f;FAN=%hu;RPM=%hu;FREQ=%u;MEMFREQ=%u;GPUF=%u;MEMF=%u;" + "PST=%s;POWER=%u;PLIM=%u;" "VID=%hx;PID=%hx;NVML=%d;NVAPI=%d;SN=%s;BIOS=%s|", gpu_id, cgpu->gpu_bus, card, cgpu->gpu_arch, (uint32_t) cgpu->gpu_mem, cgpu->gpu_temp, cgpu->gpu_fan, cgpu->gpu_fan_rpm, - cgpu->gpu_clock, cgpu->gpu_memclock, - pstate, cgpu->gpu_power, + cgpu->gpu_clock/1000U, cgpu->gpu_memclock/1000U, // base clocks + cgpu->monitor.gpu_clock, cgpu->monitor.gpu_memclock, // current + pstate, cgpu->gpu_power, cgpu->gpu_plimit, cgpu->gpu_vid, cgpu->gpu_pid, cgpu->nvml_id, cgpu->nvapi_id, cgpu->gpu_sn, cgpu->gpu_desc); @@ -329,7 +338,7 @@ static void syshwinfos() memset(buf, 0, sizeof(buf)); snprintf(buf, sizeof(buf), "OS=%s;NVDRIVER=%s;CPUS=%d;CPUTEMP=%d;CPUFREQ=%d|", - os_name(), driver_version, num_cpus, cputc, cpuclk); + os_name(), driver_version, num_cpus, cputc, cpuclk/1000); strcat(buffer, buf); } diff --git a/api/index.php b/api/index.php index 71155e3..231fc39 100644 --- a/api/index.php +++ b/api/index.php @@ -1,5 +1,5 @@ '.$val.' kH/s'; break; + case 'KHW': + $val = $val.' kH/W'; + break; case 'NAME': case 'POOL'; case 'USER': diff --git a/miner.h b/miner.h index 9446760..a555175 100644 --- a/miner.h +++ b/miner.h @@ -391,6 +391,7 @@ struct cgpu_info { uint64_t gpu_mem; uint64_t gpu_memfree; uint32_t gpu_power; + uint32_t gpu_plimit; double gpu_vddc; int16_t gpu_pstate; int16_t gpu_bus; @@ -521,6 +522,7 @@ extern char* device_name[MAX_GPUS]; extern short device_map[MAX_GPUS]; extern short device_mpcount[MAX_GPUS]; extern long device_sm[MAX_GPUS]; +extern uint32_t device_plimit[MAX_GPUS]; extern uint32_t gpus_intensity[MAX_GPUS]; extern int opt_cudaschedule; diff --git a/nvml.cpp b/nvml.cpp index f9792f8..3673825 100644 --- a/nvml.cpp +++ b/nvml.cpp @@ -34,7 +34,6 @@ static uint32_t device_bus_ids[MAX_GPUS] = { 0 }; extern uint32_t device_gpu_clocks[MAX_GPUS]; extern uint32_t device_mem_clocks[MAX_GPUS]; -extern uint32_t device_plimit[MAX_GPUS]; extern uint8_t device_tlimit[MAX_GPUS]; extern int8_t device_pstate[MAX_GPUS]; extern int32_t device_led[MAX_GPUS]; @@ -539,6 +538,19 @@ int nvml_set_plimit(nvml_handle *nvmlh, int dev_id) return 1; } +uint32_t nvml_get_plimit(nvml_handle *nvmlh, int dev_id) +{ + uint32_t plimit = 0; + int n = nvmlh ? nvmlh->cuda_nvml_device_id[dev_id] : -1; + if (n < 0 || n >= nvmlh->nvml_gpucount) + return 0; + + if (nvmlh->nvmlDeviceGetPowerManagementLimit) { + nvmlh->nvmlDeviceGetPowerManagementLimit(nvmlh->devs[n], &plimit); + } + return plimit; +} + // ccminer -D -n #define LSTDEV_PFX " " void nvml_print_device_info(int dev_id) @@ -1788,7 +1800,7 @@ int nvapi_init_settings() for (int n=0; n < opt_n_threads; n++) { int dev_id = device_map[n % MAX_GPUS]; - if (device_plimit[dev_id]) { + if (device_plimit[dev_id] && !hnvml) { if (nvapi_set_plimit(nvapi_dev_map[dev_id], device_plimit[dev_id]) == NVAPI_OK) { uint32_t res = nvapi_get_plimit(nvapi_dev_map[dev_id]); gpulog(LOG_INFO, n, "Power limit is set to %u%%", res); @@ -1952,6 +1964,23 @@ unsigned int gpu_power(struct cgpu_info *gpu) return mw; } +unsigned int gpu_plimit(struct cgpu_info *gpu) +{ + unsigned int mw = 0; + int support = -1; + if (hnvml) { + mw = nvml_get_plimit(hnvml, gpu->gpu_id); + support = (mw > 0); + } +#ifdef WIN32 + // NVAPI value is in % (< 100 so) + if (support == -1) { + mw = nvapi_get_plimit(nvapi_dev_map[gpu->gpu_id]); + } +#endif + return mw; +} + static int translate_vendor_id(uint16_t vid, char *vendorname) { struct VENDORS { @@ -2116,15 +2145,18 @@ void *monitor_thread(void *userdata) do { unsigned int tmp_clock=0, tmp_memclock=0; nvml_get_current_clocks(dev_id, &tmp_clock, &tmp_memclock); - if (tmp_clock < 200) { #ifdef WIN32 - // workaround for buggy driver 378.49 (real clock) + if (tmp_clock < 200) { + // workaround for buggy drivers 378.x (real clock) tmp_clock = nvapi_get_gpu_clock(nvapi_dev_map[dev_id]); -#else + } +#endif + if (tmp_clock < 200) { // some older cards only report a base clock with cuda props. - if (cuda_gpu_info(cgpu) == 0) + if (cuda_gpu_info(cgpu) == 0) { tmp_clock = cgpu->gpu_clock/1000; -#endif + tmp_memclock = cgpu->gpu_memclock/1000; + } } clock += tmp_clock; mem_clock += tmp_memclock; @@ -2148,14 +2180,14 @@ void *monitor_thread(void *userdata) khs_per_watt = stats_get_speed(thr_id, thr_hashrates[thr_id]); khs_per_watt = khs_per_watt / ((double)power / counter); format_hashrate(khs_per_watt * 1000, khw); - if (strlen(khw)) khw[strlen(khw)-1] = 'W'; + if (strlen(khw)) + sprintf(&khw[strlen(khw)-1], "W %uW ", cgpu->monitor.gpu_power / 1000); } if (opt_hwmonitor && (time(NULL) - cgpu->monitor.tm_displayed) > 60) { - gpulog(LOG_INFO, thr_id, "%u MHz %s %uW %uC FAN %u%%", + gpulog(LOG_INFO, thr_id, "%u MHz %s%uC FAN %u%%", cgpu->monitor.gpu_clock/*, cgpu->monitor.gpu_memclock*/, - khw, cgpu->monitor.gpu_power / 1000, - cgpu->monitor.gpu_temp, cgpu->monitor.gpu_fan + khw, cgpu->monitor.gpu_temp, cgpu->monitor.gpu_fan ); cgpu->monitor.tm_displayed = (uint32_t)time(NULL); } diff --git a/nvml.h b/nvml.h index d10b639..fd8de2f 100644 --- a/nvml.h +++ b/nvml.h @@ -211,6 +211,7 @@ unsigned int gpu_fanpercent(struct cgpu_info *gpu); unsigned int gpu_fanrpm(struct cgpu_info *gpu); float gpu_temp(struct cgpu_info *gpu); unsigned int gpu_power(struct cgpu_info *gpu); +unsigned int gpu_plimit(struct cgpu_info *gpu); int gpu_pstate(struct cgpu_info *gpu); int gpu_busid(struct cgpu_info *gpu); diff --git a/util.cpp b/util.cpp index fe55250..88d6436 100644 --- a/util.cpp +++ b/util.cpp @@ -1627,7 +1627,6 @@ static bool stratum_get_algo(struct stratum_ctx *sctx, json_t *id, json_t *param #include "nvml.h" extern char driver_version[32]; extern int cuda_arch[MAX_GPUS]; -extern uint32_t device_plimit[MAX_GPUS]; static bool json_object_set_error(json_t *result, int code, const char *msg) {