power monitoring thread + some api changes
based on alexis monitoring thread idea, but which only use one thread note: other api changes will come soon, related to that
This commit is contained in:
parent
242aa4144b
commit
0dd022779b
27
api.cpp
27
api.cpp
@ -8,7 +8,7 @@
|
|||||||
* Software Foundation; either version 2 of the License, or (at your option)
|
* Software Foundation; either version 2 of the License, or (at your option)
|
||||||
* any later version. See COPYING for more details.
|
* any later version. See COPYING for more details.
|
||||||
*/
|
*/
|
||||||
#define APIVERSION "1.8"
|
#define APIVERSION "1.9"
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
# define _WINSOCK_DEPRECATED_NO_WARNINGS
|
# define _WINSOCK_DEPRECATED_NO_WARNINGS
|
||||||
@ -112,6 +112,7 @@ static void gpustatus(int thr_id)
|
|||||||
|
|
||||||
if (thr_id >= 0 && thr_id < opt_n_threads) {
|
if (thr_id >= 0 && thr_id < opt_n_threads) {
|
||||||
struct cgpu_info *cgpu = &thr_info[thr_id].gpu;
|
struct cgpu_info *cgpu = &thr_info[thr_id].gpu;
|
||||||
|
double khashes_per_watt = 0;
|
||||||
int gpuid = cgpu->gpu_id;
|
int gpuid = cgpu->gpu_id;
|
||||||
char buf[512]; *buf = '\0';
|
char buf[512]; *buf = '\0';
|
||||||
char* card;
|
char* card;
|
||||||
@ -131,14 +132,24 @@ static void gpustatus(int thr_id)
|
|||||||
cgpu->rejected = p->rejected_count;
|
cgpu->rejected = p->rejected_count;
|
||||||
|
|
||||||
cgpu->khashes = stats_get_speed(thr_id, 0.0) / 1000.0;
|
cgpu->khashes = stats_get_speed(thr_id, 0.0) / 1000.0;
|
||||||
|
if (cgpu->monitor.gpu_power) {
|
||||||
|
cgpu->gpu_power = cgpu->monitor.gpu_power;
|
||||||
|
khashes_per_watt = (double)cgpu->khashes / cgpu->monitor.gpu_power;
|
||||||
|
khashes_per_watt *= 1000; // power in mW
|
||||||
|
//gpulog(LOG_BLUE, thr_id, "KHW: %g", khashes_per_watt);
|
||||||
|
}
|
||||||
|
|
||||||
card = device_name[gpuid];
|
card = device_name[gpuid];
|
||||||
|
|
||||||
snprintf(buf, sizeof(buf), "GPU=%d;BUS=%hd;CARD=%s;TEMP=%.1f;"
|
snprintf(buf, sizeof(buf), "GPU=%d;BUS=%hd;CARD=%s;TEMP=%.1f;"
|
||||||
"POWER=%u;FAN=%hu;RPM=%hu;FREQ=%d;KHS=%.2f;HWF=%d;I=%.1f;THR=%u|",
|
"POWER=%u;FAN=%hu;RPM=%hu;"
|
||||||
|
"FREQ=%u;CORE=%u;MEM=%u;"
|
||||||
|
"KHS=%.2f;KHW=%.5f;"
|
||||||
|
"HWF=%d;I=%.1f;THR=%u|",
|
||||||
gpuid, cgpu->gpu_bus, card, cgpu->gpu_temp,
|
gpuid, cgpu->gpu_bus, card, cgpu->gpu_temp,
|
||||||
cgpu->gpu_power, cgpu->gpu_fan, cgpu->gpu_fan_rpm,
|
cgpu->gpu_power, cgpu->gpu_fan, cgpu->gpu_fan_rpm,
|
||||||
cgpu->gpu_clock, cgpu->khashes,
|
cgpu->gpu_clock, cgpu->monitor.gpu_clock, cgpu->monitor.gpu_memclock,
|
||||||
|
cgpu->khashes, khashes_per_watt,
|
||||||
cgpu->hw_errors, cgpu->intensity, cgpu->throughput);
|
cgpu->hw_errors, cgpu->intensity, cgpu->throughput);
|
||||||
|
|
||||||
// append to buffer for multi gpus
|
// append to buffer for multi gpus
|
||||||
@ -349,7 +360,7 @@ static char *gethistory(char *params)
|
|||||||
*buffer = '\0';
|
*buffer = '\0';
|
||||||
for (int i = 0; i < records; i++) {
|
for (int i = 0; i < records; i++) {
|
||||||
time_t ts = data[i].tm_stat;
|
time_t ts = data[i].tm_stat;
|
||||||
p += sprintf(p, "GPU=%d;H=%u;KHS=%.2f;DIFF=%.6f;"
|
p += sprintf(p, "GPU=%d;H=%u;KHS=%.2f;DIFF=%g;"
|
||||||
"COUNT=%u;FOUND=%u;ID=%u;TS=%u|",
|
"COUNT=%u;FOUND=%u;ID=%u;TS=%u|",
|
||||||
data[i].gpu_id, data[i].height, data[i].hashrate, data[i].difficulty,
|
data[i].gpu_id, data[i].height, data[i].hashrate, data[i].difficulty,
|
||||||
data[i].hashcount, data[i].hashfound, data[i].uid, (uint32_t)ts);
|
data[i].hashcount, data[i].hashfound, data[i].uid, (uint32_t)ts);
|
||||||
@ -358,7 +369,7 @@ static char *gethistory(char *params)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the job scans ranges (debug purpose)
|
* Returns the job scans ranges (debug purpose, only with -D)
|
||||||
*/
|
*/
|
||||||
static char *getscanlog(char *params)
|
static char *getscanlog(char *params)
|
||||||
{
|
{
|
||||||
@ -368,9 +379,11 @@ static char *getscanlog(char *params)
|
|||||||
*buffer = '\0';
|
*buffer = '\0';
|
||||||
for (int i = 0; i < records; i++) {
|
for (int i = 0; i < records; i++) {
|
||||||
time_t ts = data[i].tm_upd;
|
time_t ts = data[i].tm_upd;
|
||||||
p += sprintf(p, "H=%u;P=%u;JOB=%u;N=%u;FROM=0x%x;SCANTO=0x%x;"
|
p += sprintf(p, "H=%u;P=%u;JOB=%u;ID=%d;DIFF=%g;"
|
||||||
|
"N=0x%x;FROM=0x%x;SCANTO=0x%x;"
|
||||||
"COUNT=0x%x;FOUND=%u;TS=%u|",
|
"COUNT=0x%x;FOUND=%u;TS=%u|",
|
||||||
data[i].height, data[i].npool, data[i].njobid, data[i].nonce, data[i].scanned_from, data[i].scanned_to,
|
data[i].height, data[i].npool, data[i].njobid, (int)data[i].job_nonce_id, data[i].sharediff,
|
||||||
|
data[i].nonce, data[i].scanned_from, data[i].scanned_to,
|
||||||
(data[i].scanned_to - data[i].scanned_from), data[i].tm_sent ? 1 : 0, (uint32_t)ts);
|
(data[i].scanned_to - data[i].scanned_from), data[i].tm_sent ? 1 : 0, (uint32_t)ts);
|
||||||
}
|
}
|
||||||
return buffer;
|
return buffer;
|
||||||
|
47
ccminer.cpp
47
ccminer.cpp
@ -85,6 +85,7 @@ bool opt_debug_threads = false;
|
|||||||
bool opt_protocol = false;
|
bool opt_protocol = false;
|
||||||
bool opt_benchmark = false;
|
bool opt_benchmark = false;
|
||||||
bool opt_showdiff = true;
|
bool opt_showdiff = true;
|
||||||
|
bool opt_hwmonitor = true;
|
||||||
|
|
||||||
// todo: limit use of these flags,
|
// todo: limit use of these flags,
|
||||||
// prefer the pools[] attributes
|
// prefer the pools[] attributes
|
||||||
@ -183,6 +184,7 @@ struct thr_api *thr_api;
|
|||||||
int longpoll_thr_id = -1;
|
int longpoll_thr_id = -1;
|
||||||
int stratum_thr_id = -1;
|
int stratum_thr_id = -1;
|
||||||
int api_thr_id = -1;
|
int api_thr_id = -1;
|
||||||
|
int monitor_thr_id = -1;
|
||||||
bool stratum_need_reset = false;
|
bool stratum_need_reset = false;
|
||||||
volatile bool abort_flag = false;
|
volatile bool abort_flag = false;
|
||||||
struct work_restart *work_restart = NULL;
|
struct work_restart *work_restart = NULL;
|
||||||
@ -1684,6 +1686,7 @@ static void *miner_thread(void *userdata)
|
|||||||
int switchn = pool_switch_count;
|
int switchn = pool_switch_count;
|
||||||
int thr_id = mythr->id;
|
int thr_id = mythr->id;
|
||||||
int dev_id = device_map[thr_id % MAX_GPUS];
|
int dev_id = device_map[thr_id % MAX_GPUS];
|
||||||
|
struct cgpu_info * cgpu = &thr_info[thr_id].gpu;
|
||||||
struct work work;
|
struct work work;
|
||||||
uint64_t loopcnt = 0;
|
uint64_t loopcnt = 0;
|
||||||
uint32_t max_nonce;
|
uint32_t max_nonce;
|
||||||
@ -2142,6 +2145,11 @@ static void *miner_thread(void *userdata)
|
|||||||
if (opt_led_mode == LED_MODE_MINING)
|
if (opt_led_mode == LED_MODE_MINING)
|
||||||
gpu_led_on(dev_id);
|
gpu_led_on(dev_id);
|
||||||
|
|
||||||
|
if (cgpu && loopcnt > 1) {
|
||||||
|
cgpu->monitor.sampling_flag = true;
|
||||||
|
pthread_cond_signal(&cgpu->monitor.sampling_signal);
|
||||||
|
}
|
||||||
|
|
||||||
hashes_done = 0;
|
hashes_done = 0;
|
||||||
gettimeofday(&tv_start, NULL);
|
gettimeofday(&tv_start, NULL);
|
||||||
|
|
||||||
@ -2350,6 +2358,10 @@ static void *miner_thread(void *userdata)
|
|||||||
|
|
||||||
timeval_subtract(&diff, &tv_end, &tv_start);
|
timeval_subtract(&diff, &tv_end, &tv_start);
|
||||||
|
|
||||||
|
if (cgpu && diff.tv_sec) { // stop monitoring
|
||||||
|
cgpu->monitor.sampling_flag = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (diff.tv_usec || diff.tv_sec) {
|
if (diff.tv_usec || diff.tv_sec) {
|
||||||
double dtime = (double) diff.tv_sec + 1e-6 * diff.tv_usec;
|
double dtime = (double) diff.tv_sec + 1e-6 * diff.tv_usec;
|
||||||
|
|
||||||
@ -3805,7 +3817,7 @@ int main(int argc, char *argv[])
|
|||||||
if (!work_restart)
|
if (!work_restart)
|
||||||
return EXIT_CODE_SW_INIT_ERROR;
|
return EXIT_CODE_SW_INIT_ERROR;
|
||||||
|
|
||||||
thr_info = (struct thr_info *)calloc(opt_n_threads + 4, sizeof(*thr));
|
thr_info = (struct thr_info *)calloc(opt_n_threads + 5, sizeof(*thr));
|
||||||
if (!thr_info)
|
if (!thr_info)
|
||||||
return EXIT_CODE_SW_INIT_ERROR;
|
return EXIT_CODE_SW_INIT_ERROR;
|
||||||
|
|
||||||
@ -3914,6 +3926,22 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_WRAPNVML
|
||||||
|
// to monitor gpu activitity during work, a thread is required
|
||||||
|
if (1) {
|
||||||
|
monitor_thr_id = opt_n_threads + 4;
|
||||||
|
thr = &thr_info[monitor_thr_id];
|
||||||
|
thr->id = monitor_thr_id;
|
||||||
|
thr->q = tq_new();
|
||||||
|
if (!thr->q)
|
||||||
|
return EXIT_CODE_SW_INIT_ERROR;
|
||||||
|
if (unlikely(pthread_create(&thr->pth, NULL, monitor_thread, thr))) {
|
||||||
|
applog(LOG_ERR, "Monitoring thread %d create failed", i);
|
||||||
|
return EXIT_CODE_SW_INIT_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* start mining threads */
|
/* start mining threads */
|
||||||
for (i = 0; i < opt_n_threads; i++) {
|
for (i = 0; i < opt_n_threads; i++) {
|
||||||
thr = &thr_info[i];
|
thr = &thr_info[i];
|
||||||
@ -3926,6 +3954,9 @@ int main(int argc, char *argv[])
|
|||||||
if (!thr->q)
|
if (!thr->q)
|
||||||
return EXIT_CODE_SW_INIT_ERROR;
|
return EXIT_CODE_SW_INIT_ERROR;
|
||||||
|
|
||||||
|
pthread_mutex_init(&thr->gpu.monitor.lock, NULL);
|
||||||
|
pthread_cond_init(&thr->gpu.monitor.sampling_signal, NULL);
|
||||||
|
|
||||||
if (unlikely(pthread_create(&thr->pth, NULL, miner_thread, thr))) {
|
if (unlikely(pthread_create(&thr->pth, NULL, miner_thread, thr))) {
|
||||||
applog(LOG_ERR, "thread %d create failed", i);
|
applog(LOG_ERR, "thread %d create failed", i);
|
||||||
return EXIT_CODE_SW_INIT_ERROR;
|
return EXIT_CODE_SW_INIT_ERROR;
|
||||||
@ -3944,9 +3975,21 @@ int main(int argc, char *argv[])
|
|||||||
/* main loop - simply wait for workio thread to exit */
|
/* main loop - simply wait for workio thread to exit */
|
||||||
pthread_join(thr_info[work_thr_id].pth, NULL);
|
pthread_join(thr_info[work_thr_id].pth, NULL);
|
||||||
|
|
||||||
|
abort_flag = true;
|
||||||
|
|
||||||
/* wait for mining threads */
|
/* wait for mining threads */
|
||||||
for (i = 0; i < opt_n_threads; i++)
|
for (i = 0; i < opt_n_threads; i++) {
|
||||||
|
struct cgpu_info *cgpu = &thr_info[i].gpu;
|
||||||
|
if (monitor_thr_id != -1 && cgpu) {
|
||||||
|
pthread_cond_signal(&cgpu->monitor.sampling_signal);
|
||||||
|
}
|
||||||
pthread_join(thr_info[i].pth, NULL);
|
pthread_join(thr_info[i].pth, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (monitor_thr_id != -1) {
|
||||||
|
pthread_join(thr_info[monitor_thr_id].pth, NULL);
|
||||||
|
//tq_free(thr_info[monitor_thr_id].q);
|
||||||
|
}
|
||||||
|
|
||||||
if (opt_debug)
|
if (opt_debug)
|
||||||
applog(LOG_DEBUG, "workio thread dead, exiting.");
|
applog(LOG_DEBUG, "workio thread dead, exiting.");
|
||||||
|
15
miner.h
15
miner.h
@ -361,6 +361,19 @@ extern void free_scrypt_jane(int thr_id);
|
|||||||
void *api_thread(void *userdata);
|
void *api_thread(void *userdata);
|
||||||
void api_set_throughput(int thr_id, uint32_t throughput);
|
void api_set_throughput(int thr_id, uint32_t throughput);
|
||||||
|
|
||||||
|
struct monitor_info {
|
||||||
|
uint32_t gpu_temp;
|
||||||
|
uint32_t gpu_fan;
|
||||||
|
uint32_t gpu_clock;
|
||||||
|
uint32_t gpu_memclock;
|
||||||
|
uint32_t gpu_power;
|
||||||
|
|
||||||
|
pthread_mutex_t lock;
|
||||||
|
pthread_cond_t sampling_signal;
|
||||||
|
volatile bool sampling_flag;
|
||||||
|
uint32_t tm_displayed;
|
||||||
|
};
|
||||||
|
|
||||||
struct cgpu_info {
|
struct cgpu_info {
|
||||||
uint8_t gpu_id;
|
uint8_t gpu_id;
|
||||||
uint8_t thr_id;
|
uint8_t thr_id;
|
||||||
@ -391,6 +404,8 @@ struct cgpu_info {
|
|||||||
char gpu_desc[64];
|
char gpu_desc[64];
|
||||||
double intensity;
|
double intensity;
|
||||||
uint32_t throughput;
|
uint32_t throughput;
|
||||||
|
|
||||||
|
struct monitor_info monitor;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct thr_api {
|
struct thr_api {
|
||||||
|
110
nvml.cpp
110
nvml.cpp
@ -418,6 +418,25 @@ int nvml_reset_clocks(nvml_handle *nvmlh, int dev_id)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int nvml_get_clocks(nvml_handle *nvmlh, int dev_id, unsigned int *core, unsigned int *mem)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
nvmlReturn_t rc;
|
||||||
|
uint32_t gpu_clk = 0, mem_clk = 0;
|
||||||
|
int n = nvmlh->cuda_nvml_device_id[dev_id];
|
||||||
|
if (n < 0 || n >= nvmlh->nvml_gpucount)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
if (nvmlh->nvmlDeviceGetClockInfo) {
|
||||||
|
rc = nvmlh->nvmlDeviceGetClockInfo(nvmlh->devs[n], NVML_CLOCK_SM, &gpu_clk);
|
||||||
|
rc = nvmlh->nvmlDeviceGetClockInfo(nvmlh->devs[n], NVML_CLOCK_MEM, &mem_clk);
|
||||||
|
if (rc == NVML_SUCCESS) {
|
||||||
|
*core = gpu_clk; *mem = mem_clk;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set power state of a device (9xx)
|
* Set power state of a device (9xx)
|
||||||
@ -639,6 +658,21 @@ int nvml_get_fanpcnt(nvml_handle *nvmlh, int cudaindex, unsigned int *fanpcnt)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int nvml_get_current_clocks(int cudaindex, uint32_t *graphics_clock, uint32_t *mem_clock)
|
||||||
|
{
|
||||||
|
nvmlReturn_t rc;
|
||||||
|
int gpuindex = hnvml->cuda_nvml_device_id[cudaindex];
|
||||||
|
if (gpuindex < 0 || gpuindex >= hnvml->nvml_gpucount) return -1;
|
||||||
|
|
||||||
|
rc = hnvml->nvmlDeviceGetClockInfo(hnvml->devs[gpuindex], NVML_CLOCK_SM, graphics_clock);
|
||||||
|
if (rc != NVML_SUCCESS) return -1;
|
||||||
|
rc = hnvml->nvmlDeviceGetClockInfo(hnvml->devs[gpuindex], NVML_CLOCK_MEM, mem_clock);
|
||||||
|
if (rc != NVML_SUCCESS) return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Not Supported on 750Ti 340.23 */
|
/* Not Supported on 750Ti 340.23 */
|
||||||
int nvml_get_power_usage(nvml_handle *nvmlh, int cudaindex, unsigned int *milliwatts)
|
int nvml_get_power_usage(nvml_handle *nvmlh, int cudaindex, unsigned int *milliwatts)
|
||||||
{
|
{
|
||||||
@ -2051,3 +2085,79 @@ void gpu_led_off(int dev_id)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_WRAPNVML
|
||||||
|
extern double thr_hashrates[MAX_GPUS];
|
||||||
|
extern bool opt_debug_threads;
|
||||||
|
extern bool opt_hwmonitor;
|
||||||
|
extern int num_cpus;
|
||||||
|
|
||||||
|
void *monitor_thread(void *userdata)
|
||||||
|
{
|
||||||
|
//struct thr_info *mythr = (struct thr_info *)userdata;
|
||||||
|
int thr_id = -1;
|
||||||
|
|
||||||
|
while (!abort_flag && !opt_quiet)
|
||||||
|
{
|
||||||
|
// This thread monitors card's power lazily during scans, one at a time...
|
||||||
|
thr_id = (thr_id + 1) % opt_n_threads;
|
||||||
|
struct cgpu_info *cgpu = &thr_info[thr_id].gpu;
|
||||||
|
int dev_id = cgpu->gpu_id; cudaSetDevice(dev_id);
|
||||||
|
|
||||||
|
//applog(LOG_BLUE, "sampling device %d", dev_id);
|
||||||
|
if (hnvml != NULL && cgpu)
|
||||||
|
{
|
||||||
|
uint64_t clock = 0, mem_clock = 0;
|
||||||
|
uint32_t fanpercent = 0, power = 0;
|
||||||
|
double tempC = 0, khs_per_watt = 0;
|
||||||
|
uint32_t counter = 0;
|
||||||
|
int max_loops = 2000;
|
||||||
|
|
||||||
|
pthread_cond_wait(&cgpu->monitor.sampling_signal, &cgpu->monitor.lock);
|
||||||
|
|
||||||
|
do {
|
||||||
|
uint32_t tmp_clock, tmp_memclock;
|
||||||
|
nvml_get_current_clocks(device_map[thr_id], &tmp_clock, &tmp_memclock);
|
||||||
|
clock += tmp_clock;
|
||||||
|
mem_clock += tmp_memclock;
|
||||||
|
tempC += gpu_temp(cgpu);
|
||||||
|
fanpercent += gpu_fanpercent(cgpu);
|
||||||
|
power += gpu_power(cgpu);
|
||||||
|
counter++;
|
||||||
|
|
||||||
|
usleep(50000);
|
||||||
|
if (abort_flag) goto abort;
|
||||||
|
|
||||||
|
} while (cgpu->monitor.sampling_flag && (--max_loops));
|
||||||
|
|
||||||
|
cgpu->monitor.gpu_temp = (uint32_t) (tempC/counter);
|
||||||
|
cgpu->monitor.gpu_fan = fanpercent/counter;
|
||||||
|
cgpu->monitor.gpu_power = power/counter;
|
||||||
|
cgpu->monitor.gpu_clock = (uint32_t) (clock/counter);
|
||||||
|
cgpu->monitor.gpu_memclock = (uint32_t) (mem_clock/counter);
|
||||||
|
|
||||||
|
if (power) {
|
||||||
|
// todo: handle units
|
||||||
|
khs_per_watt = stats_get_speed(thr_id, thr_hashrates[thr_id]) / ((double)power / counter);
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo: not shown on decred
|
||||||
|
if (opt_hwmonitor && (time(NULL) - cgpu->monitor.tm_displayed) > 60) {
|
||||||
|
gpulog(LOG_INFO, thr_id, "%u MHz %.3f kH/W %uW %uC FAN %u%%",
|
||||||
|
cgpu->monitor.gpu_clock/*, cgpu->monitor.gpu_memclock*/,
|
||||||
|
khs_per_watt, cgpu->monitor.gpu_power / 1000,
|
||||||
|
cgpu->monitor.gpu_temp, cgpu->monitor.gpu_fan
|
||||||
|
);
|
||||||
|
cgpu->monitor.tm_displayed = (uint32_t)time(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&cgpu->monitor.lock);
|
||||||
|
}
|
||||||
|
usleep(500); // safety
|
||||||
|
}
|
||||||
|
abort:
|
||||||
|
if (opt_debug_threads)
|
||||||
|
applog(LOG_DEBUG, "%s() died", __func__);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
4
nvml.h
4
nvml.h
@ -17,6 +17,8 @@
|
|||||||
|
|
||||||
#include "miner.h"
|
#include "miner.h"
|
||||||
|
|
||||||
|
void *monitor_thread(void *userdata);
|
||||||
|
|
||||||
typedef void * nvmlDevice_t;
|
typedef void * nvmlDevice_t;
|
||||||
|
|
||||||
/* our own version of the PCI info struct */
|
/* our own version of the PCI info struct */
|
||||||
@ -212,6 +214,8 @@ unsigned int gpu_power(struct cgpu_info *gpu);
|
|||||||
int gpu_pstate(struct cgpu_info *gpu);
|
int gpu_pstate(struct cgpu_info *gpu);
|
||||||
int gpu_busid(struct cgpu_info *gpu);
|
int gpu_busid(struct cgpu_info *gpu);
|
||||||
|
|
||||||
|
void gpu_current_clocks(struct cgpu_info *gpu);
|
||||||
|
|
||||||
// pid/vid, sn and bios rev
|
// pid/vid, sn and bios rev
|
||||||
int gpu_info(struct cgpu_info *gpu);
|
int gpu_info(struct cgpu_info *gpu);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user