feat: thread benchmark, GPU-aware idle mining, thread scaling fix
- Add pool mining thread benchmark: cycles through thread counts with 20s warmup + 10s measurement to find optimal setting for CPU - Add GPU-aware idle detection: GPU utilization >= 10% (video, games) treats system as active; toggle in mining tab header (default: on) Supports AMD sysfs, NVIDIA nvidia-smi, Intel freq ratio; -1 on macOS - Fix idle thread scaling: use getRequestedThreads() for immediate thread count instead of xmrig API threads_active which lags on restart - Apply active thread count on initial mining start when user is active - Skip idle mining adjustments while benchmark is running - Disable thread grid drag-to-select during benchmark - Add idle_gpu_aware setting with JSON persistence (default: true) - Add 7 i18n English strings for benchmark and GPU-aware tooltips
This commit is contained in:
@@ -688,5 +688,106 @@ int Platform::getSystemIdleSeconds()
|
||||
#endif
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// GPU utilization detection
|
||||
// ============================================================================
|
||||
|
||||
int Platform::getGpuUtilization()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
// Windows: read GPU utilization via SetupAPI / D3DKMT
|
||||
// Not all GPUs expose this; return -1 if unavailable.
|
||||
// Use a popen fallback: nvidia-smi for NVIDIA, or return -1.
|
||||
static bool s_tried_nvidia = false;
|
||||
static bool s_has_nvidia = false;
|
||||
if (!s_tried_nvidia) {
|
||||
s_tried_nvidia = true;
|
||||
FILE* f = _popen("where nvidia-smi 2>nul", "r");
|
||||
if (f) {
|
||||
char buf[256];
|
||||
s_has_nvidia = (fgets(buf, sizeof(buf), f) != nullptr);
|
||||
_pclose(f);
|
||||
}
|
||||
}
|
||||
if (s_has_nvidia) {
|
||||
FILE* f = _popen("nvidia-smi --query-gpu=utilization.gpu --format=csv,noheader,nounits 2>nul", "r");
|
||||
if (f) {
|
||||
char buf[64];
|
||||
int util = -1;
|
||||
if (fgets(buf, sizeof(buf), f)) {
|
||||
util = atoi(buf);
|
||||
if (util < 0 || util > 100) util = -1;
|
||||
}
|
||||
_pclose(f);
|
||||
return util;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
#elif defined(__APPLE__)
|
||||
return -1;
|
||||
#else
|
||||
// Linux: try multiple GPU sysfs paths
|
||||
|
||||
// AMD: /sys/class/drm/card*/device/gpu_busy_percent
|
||||
{
|
||||
// Try card0 through card3
|
||||
char path[128];
|
||||
for (int i = 0; i < 4; i++) {
|
||||
snprintf(path, sizeof(path), "/sys/class/drm/card%d/device/gpu_busy_percent", i);
|
||||
std::ifstream ifs(path);
|
||||
if (ifs.is_open()) {
|
||||
int val = -1;
|
||||
ifs >> val;
|
||||
if (val >= 0 && val <= 100)
|
||||
return val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NVIDIA: nvidia-smi (binary may exist even without sysfs)
|
||||
{
|
||||
static bool s_tried = false;
|
||||
static bool s_has_nvidia_smi = false;
|
||||
if (!s_tried) {
|
||||
s_tried = true;
|
||||
FILE* f = popen("which nvidia-smi 2>/dev/null", "r");
|
||||
if (f) {
|
||||
char buf[256];
|
||||
s_has_nvidia_smi = (fgets(buf, sizeof(buf), f) != nullptr);
|
||||
pclose(f);
|
||||
}
|
||||
}
|
||||
if (s_has_nvidia_smi) {
|
||||
FILE* f = popen("nvidia-smi --query-gpu=utilization.gpu --format=csv,noheader,nounits 2>/dev/null", "r");
|
||||
if (f) {
|
||||
char buf[64];
|
||||
int util = -1;
|
||||
if (fgets(buf, sizeof(buf), f)) {
|
||||
util = atoi(buf);
|
||||
if (util < 0 || util > 100) util = -1;
|
||||
}
|
||||
pclose(f);
|
||||
return util;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Intel: compare current vs max freq as a rough proxy
|
||||
{
|
||||
std::ifstream curF("/sys/class/drm/card0/gt_cur_freq_mhz");
|
||||
std::ifstream maxF("/sys/class/drm/card0/gt_max_freq_mhz");
|
||||
if (curF.is_open() && maxF.is_open()) {
|
||||
int cur = 0, mx = 0;
|
||||
curF >> cur;
|
||||
maxF >> mx;
|
||||
if (mx > 0)
|
||||
return std::min(100, (cur * 100) / mx);
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace util
|
||||
} // namespace dragonx
|
||||
|
||||
Reference in New Issue
Block a user