Browse Source

stats: add support for current freq and pstate

windows only via nvapi, if nvml function is not supported
master
Tanguy Pruvot 10 years ago
parent
commit
3d2260acc4
  1. 15
      api.cpp
  2. 3
      api/index.php
  3. 2
      ccminer.cpp
  4. 83
      nvml.cpp

15
api.cpp

@ -128,7 +128,7 @@ static void gpustatus(int thr_id)
cgpu->gpu_temp = gpu_temp(cgpu); cgpu->gpu_temp = gpu_temp(cgpu);
cgpu->gpu_fan = gpu_fanpercent(cgpu); cgpu->gpu_fan = gpu_fanpercent(cgpu);
cgpu->gpu_power = gpu_power(cgpu); cgpu->gpu_power = gpu_power(cgpu);
//cgpu->gpu_clock = gpu_clock(cgpu); cgpu->gpu_clock = gpu_clock(cgpu);
} }
#endif #endif
@ -149,9 +149,10 @@ static void gpustatus(int thr_id)
cgpu->khashes = stats_get_speed(thr_id) / 1000.0; cgpu->khashes = stats_get_speed(thr_id) / 1000.0;
sprintf(buf, "GPU=%d;TEMP=%.1f;FAN=%d;POWER=%d;KHS=%.2f;" sprintf(buf, "GPU=%d;TEMP=%.1f;FAN=%d;FREQ=%d;POWER=%d;KHS=%.2f;"
"HWF=%d;I=%d|", "HWF=%d;I=%d|",
thr_id, cgpu->gpu_temp, cgpu->gpu_fan, cgpu->gpu_power, cgpu->khashes, thr_id, cgpu->gpu_temp, cgpu->gpu_fan,
cgpu->gpu_clock, cgpu->gpu_power, cgpu->khashes,
cgpu->hw_errors, cgpu->intensity); cgpu->hw_errors, cgpu->intensity);
strcat(buffer, buf); strcat(buffer, buf);
@ -457,9 +458,11 @@ static void api()
connectaddr, addrok ? "Accepted" : "Ignored"); connectaddr, addrok ? "Accepted" : "Ignored");
if (addrok) { if (addrok) {
bool fail;
n = recv(c, &buf[0], SOCK_REC_BUFSZ, 0); n = recv(c, &buf[0], SOCK_REC_BUFSZ, 0);
if (SOCKETFAIL(n)) fail = SOCKETFAIL(n);
if (fail)
buf[0] = '\0'; buf[0] = '\0';
else if (n > 0 && buf[n-1] == '\n') { else if (n > 0 && buf[n-1] == '\n') {
/* telnet compat \r\n */ /* telnet compat \r\n */
@ -469,10 +472,10 @@ static void api()
} }
buf[n] = '\0'; buf[n] = '\0';
if (opt_debug && opt_protocol) if (opt_debug && opt_protocol && n > 0)
applog(LOG_DEBUG, "API: recv command: (%d) '%s'+char(%x)", n, buf, buf[n-1]); applog(LOG_DEBUG, "API: recv command: (%d) '%s'+char(%x)", n, buf, buf[n-1]);
if (!SOCKETFAIL(n)) { if (!fail) {
params = strchr(buf, '|'); params = strchr(buf, '|');
if (params != NULL) if (params != NULL)
*(params++) = '\0'; *(params++) = '\0';

3
api/index.php

@ -35,6 +35,7 @@ function translateField($key)
$intl['TEMP'] = 'T°c'; $intl['TEMP'] = 'T°c';
$intl['FAN'] = 'Fan %'; $intl['FAN'] = 'Fan %';
$intl['FREQ'] = 'Freq.';
if (isset($intl[$key])) if (isset($intl[$key]))
return $intl[$key]; return $intl[$key];
@ -160,4 +161,4 @@ li span.algo { display: inline-block; width: 50px; max-width: 120px; }
</div> </div>
</body> </body>
</html> </html>

2
ccminer.cpp

@ -2131,7 +2131,7 @@ int main(int argc, char *argv[])
if (hnvml) if (hnvml)
applog(LOG_INFO, "NVML GPU monitoring enabled."); applog(LOG_INFO, "NVML GPU monitoring enabled.");
#ifdef WIN32 /* _WIN32 = x86 only, WIN32 for both _WIN32 & _WIN64 */ #ifdef WIN32 /* _WIN32 = x86 only, WIN32 for both _WIN32 & _WIN64 */
else if (wrap_nvapi_init() == -1) else if (wrap_nvapi_init() == 0)
applog(LOG_INFO, "NVAPI GPU monitoring enabled."); applog(LOG_INFO, "NVAPI GPU monitoring enabled.");
#endif #endif
else else

83
nvml.cpp

@ -280,8 +280,8 @@ int wrap_nvml_get_clock(wrap_nvml_handle *nvmlh, int cudaindex, int type, unsign
wrap_nvmlReturn_t res = nvmlh->nvmlDeviceGetClockInfo(nvmlh->devs[gpuindex], (wrap_nvmlClockType_t) type, freq); wrap_nvmlReturn_t res = nvmlh->nvmlDeviceGetClockInfo(nvmlh->devs[gpuindex], (wrap_nvmlClockType_t) type, freq);
if (res != WRAPNVML_SUCCESS) { if (res != WRAPNVML_SUCCESS) {
if (opt_debug) //if (opt_debug)
applog(LOG_DEBUG, "nvmlDeviceGetClockInfo: %s", nvmlh->nvmlErrorString(res)); // applog(LOG_DEBUG, "nvmlDeviceGetClockInfo: %s", nvmlh->nvmlErrorString(res));
return -1; return -1;
} }
@ -297,8 +297,8 @@ int wrap_nvml_get_power_usage(wrap_nvml_handle *nvmlh, int cudaindex, unsigned i
wrap_nvmlReturn_t res = nvmlh->nvmlDeviceGetPowerUsage(nvmlh->devs[gpuindex], milliwatts); wrap_nvmlReturn_t res = nvmlh->nvmlDeviceGetPowerUsage(nvmlh->devs[gpuindex], milliwatts);
if (res != WRAPNVML_SUCCESS) { if (res != WRAPNVML_SUCCESS) {
if (opt_debug) //if (opt_debug)
applog(LOG_DEBUG, "nvmlDeviceGetPowerUsage: %s", nvmlh->nvmlErrorString(res)); // applog(LOG_DEBUG, "nvmlDeviceGetPowerUsage: %s", nvmlh->nvmlErrorString(res));
return -1; return -1;
} }
@ -365,7 +365,6 @@ int nvapi_temperature(unsigned int devNum, unsigned int *temperature)
return 0; return 0;
} }
int nvapi_fanspeed(unsigned int devNum, unsigned int *speed) int nvapi_fanspeed(unsigned int devNum, unsigned int *speed)
{ {
NvAPI_Status ret; NvAPI_Status ret;
@ -388,6 +387,55 @@ int nvapi_fanspeed(unsigned int devNum, unsigned int *speed)
return 0; return 0;
} }
int nvapi_getclock(unsigned int devNum, unsigned int *freq)
{
NvAPI_Status ret;
if (devNum >= nvapi_dev_cnt)
return -1;
NV_GPU_CLOCK_FREQUENCIES_V2 clocks;
clocks.version = NV_GPU_CLOCK_FREQUENCIES_VER_2;
clocks.ClockType = NV_GPU_CLOCK_FREQUENCIES_CURRENT_FREQ; // CURRENT/BASE/BOOST
ret = NvAPI_GPU_GetAllClockFrequencies(phys[devNum], &clocks);
if (ret != NVAPI_OK) {
NvAPI_ShortString string;
NvAPI_GetErrorMessage(ret, string);
if (opt_debug)
applog(LOG_DEBUG, "NVAPI NvAPI_GPU_GetAllClockFrequencies: %s", string);
return -1;
} else {
// GRAPHICS/MEMORY
(*freq) = (unsigned int)clocks.domain[NVAPI_GPU_PUBLIC_CLOCK_GRAPHICS].frequency;
}
return 0;
}
int nvapi_getpower(unsigned int devNum, unsigned int *power)
{
NvAPI_Status ret;
if (devNum >= nvapi_dev_cnt)
return -1;
NV_GPU_PERF_PSTATE_ID CurrentPstate = NVAPI_GPU_PERF_PSTATE_UNDEFINED; /* 16 */
ret = NvAPI_GPU_GetCurrentPstate(phys[devNum], &CurrentPstate);
if (ret != NVAPI_OK) {
NvAPI_ShortString string;
NvAPI_GetErrorMessage(ret, string);
if (opt_debug)
applog(LOG_DEBUG, "NVAPI NvAPI_GPU_GetCurrentPstate: %s", string);
return -1;
}
else {
// get pstate for the moment... often 0 = P0
(*power) = (unsigned int)CurrentPstate;
}
return 0;
}
int wrap_nvapi_init() int wrap_nvapi_init()
{ {
NvAPI_Status ret = NvAPI_Initialize(); NvAPI_Status ret = NvAPI_Initialize();
@ -426,8 +474,10 @@ int wrap_nvapi_init()
} }
#endif #endif
/* api functions */ /* api functions -------------------------------------- */
static unsigned int fan_speed_max = 2000; /* assume 2000 rpm as default, auto-updated */
// assume 2500 rpm as default, auto-updated if more
static unsigned int fan_speed_max = 2500;
unsigned int gpu_fanpercent(struct cgpu_info *gpu) unsigned int gpu_fanpercent(struct cgpu_info *gpu)
{ {
@ -469,18 +519,33 @@ double gpu_temp(struct cgpu_info *gpu)
unsigned int gpu_clock(struct cgpu_info *gpu) unsigned int gpu_clock(struct cgpu_info *gpu)
{ {
unsigned int freq = 0; unsigned int freq = 0;
int support = -1;
if (hnvml) { if (hnvml) {
wrap_nvml_get_clock(hnvml, device_map[gpu->thr_id], NVML_CLOCK_SM, &freq); support = wrap_nvml_get_clock(hnvml, device_map[gpu->thr_id], NVML_CLOCK_SM, &freq);
} }
#ifdef WIN32
if (support == -1) {
nvapi_getclock(device_map[gpu->thr_id], &freq);
}
#endif
return freq; return freq;
} }
unsigned int gpu_power(struct cgpu_info *gpu) unsigned int gpu_power(struct cgpu_info *gpu)
{ {
unsigned int mw = 0; unsigned int mw = 0;
int support = -1;
if (hnvml) { if (hnvml) {
wrap_nvml_get_power_usage(hnvml, device_map[gpu->thr_id], &mw); support = wrap_nvml_get_power_usage(hnvml, device_map[gpu->thr_id], &mw);
} }
#ifdef WIN32
if (support == -1) {
unsigned int pstate = 0;
nvapi_getpower(device_map[gpu->thr_id], &pstate);
//todo : convert ?
mw = pstate;
}
#endif
return mw; return mw;
} }

Loading…
Cancel
Save