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) {