From d6046d137085cabf2b59bbc7ce378ea74f2bc086 Mon Sep 17 00:00:00 2001 From: Omar Alvarez Date: Mon, 31 Oct 2016 12:32:03 +0100 Subject: [PATCH 1/2] Multi-GPU and genproclimit for maximizing GPU usage support --- src/libstratum/ZcashStratum.cpp | 2 +- src/libzogminer/cl_zogminer.h | 4 +- src/libzogminer/gpuconfig.h | 6 +- src/standaloneminer.cpp | 167 +++++++++++++++++++++++++++++--- 4 files changed, 159 insertions(+), 20 deletions(-) diff --git a/src/libstratum/ZcashStratum.cpp b/src/libstratum/ZcashStratum.cpp index 8d3deb3..519e3be 100644 --- a/src/libstratum/ZcashStratum.cpp +++ b/src/libstratum/ZcashStratum.cpp @@ -300,7 +300,7 @@ void ZcashMiner::start() minerThreads = new boost::thread_group(); for (int i = 0; i < nThreads; i++) { minerThreads->create_thread(boost::bind(&ZcashMinerThread, this, nThreads, i, conf)); - } + } } void ZcashMiner::stop() diff --git a/src/libzogminer/cl_zogminer.h b/src/libzogminer/cl_zogminer.h index fd49408..f487095 100644 --- a/src/libzogminer/cl_zogminer.h +++ b/src/libzogminer/cl_zogminer.h @@ -80,6 +80,8 @@ class cl_zogminer static unsigned getNumDevices(unsigned _platformId = 0); static std::string platform_info(unsigned _platformId = 0, unsigned _deviceId = 0); static void listDevices(); + static std::vector getDevices(std::vector const& _platforms, unsigned _platformId); + static std::vector getPlatforms(); // Currently just prints memory of the GPU static bool configureGPU( @@ -112,8 +114,6 @@ class cl_zogminer static const size_t z_collision_bit_length = z_n / (z_k + 1); static const eh_index z_N = 1 << (z_collision_bit_length + 1); - static std::vector getDevices(std::vector const& _platforms, unsigned _platformId); - static std::vector getPlatforms(); int compare_indices32(uint32_t* a, uint32_t* b, size_t n_current_indices) { for(size_t i = 0; i < n_current_indices; ++i, ++a, ++b) { if(*a < *b) { diff --git a/src/libzogminer/gpuconfig.h b/src/libzogminer/gpuconfig.h index 6878fa0..a6226cc 100644 --- a/src/libzogminer/gpuconfig.h +++ b/src/libzogminer/gpuconfig.h @@ -31,7 +31,11 @@ class GPUConfig { //~GPUConfig(); bool useGPU; - int64_t selGPU; + unsigned selGPU; + bool allGPU; + bool forceGenProcLimit; + unsigned currentPlatform; + unsigned currentDevice; unsigned globalWorkSize; unsigned workgroupSize; diff --git a/src/standaloneminer.cpp b/src/standaloneminer.cpp index 3a70607..5dfe201 100644 --- a/src/standaloneminer.cpp +++ b/src/standaloneminer.cpp @@ -244,8 +244,11 @@ int main(int argc, char* argv[]) GPUConfig conf; - conf.useGPU = GetBoolArg("-G", false); + conf.useGPU = GetBoolArg("-G", false) || GetBoolArg("-GPU", false); conf.selGPU = GetArg("-S", 0); + conf.allGPU = GetBoolArg("-allgpu", false); + conf.forceGenProcLimit = GetBoolArg("-forcenolimit", false); + int nThreads = GetArg("-genproclimit", 1); //std::cout << GPU << " " << selGPU << std::endl; // Zcash debugging @@ -290,22 +293,154 @@ int main(int argc, char* argv[]) return false; } - ZcashMiner miner(GetArg("-genproclimit", 1), conf); - ZcashStratumClient sc { - &miner, host, port, - GetArg("-user", "x"), - GetArg("-password", "x"), - 0, 0 - }; - - miner.onSolutionFound([&](const EquihashSolution& solution) { - return sc.submit(&solution); - }); - - scSig = ≻ - signal(SIGINT, stratum_sigint_handler); + std::vector sClients; + std::vector sMiners; + + // If using GPU + if(conf.useGPU) { + + conf.currentPlatform = 0; + conf.currentDevice = conf.selGPU; + + std::vector platforms = cl_zogminer::getPlatforms(); + + // use all available GPUs + if(conf.allGPU) { + + int devicesFound = 0; + unsigned numPlatforms = platforms.size(); + + for(unsigned platform = 0; platform < numPlatforms; ++platform) { + + std::vector devices = cl_zogminer::getDevices(platforms, platform); + unsigned noDevices = devices.size(); + devicesFound += noDevices; + for(unsigned device = 0; device < noDevices; ++device) { + + conf.currentPlatform = platform; + conf.currentDevice = device; + + cl_ulong result; + devices[device].getInfo(CL_DEVICE_GLOBAL_MEM_SIZE, &result); + + int maxThreads = nThreads; + if (!conf.forceGenProcLimit) { + if (result > 7500000000) { + maxThreads = std::min(4, nThreads); + } else if (result > 5500000000) { + maxThreads = std::min(3, nThreads); + } else if (result > 3500000000) { + maxThreads = std::min(2, nThreads); + } else { + maxThreads = std::min(1, nThreads); + } + } + + LogPrintf("ZcashMiner GPU[%d][%d] MemLimit: %s nThreads: %d\n", platform, device, std::to_string(result), maxThreads); + + for (int i = 0; i < maxThreads; i++) { + ZcashMiner * miner = new ZcashMiner(1, conf); + sMiners.push_back(miner); + ZcashStratumClient * sc = new ZcashStratumClient{ + miner, host, port, + GetArg("-user", "x"), + GetArg("-password", "x"), + 0, 0 + }; + sClients.push_back(sc); + + miner->onSolutionFound([&](const EquihashSolution& solution) { + return sc->submit(&solution); + }); + + scSig = sc; + signal(SIGINT, stratum_sigint_handler); + } + + } + } + + if (devicesFound <= 0) { + LogPrintf("ZcashMiner ERROR, No OpenCL devices found!\n"); + } + + } else { + + // mine on specified GPU device + std::vector devices = cl_zogminer::getDevices(platforms, conf.currentPlatform); + + if (devices.size() > conf.currentDevice) { + + cl_ulong result; + devices[conf.currentDevice].getInfo(CL_DEVICE_GLOBAL_MEM_SIZE, &result); + + int maxThreads = nThreads; + if (!conf.forceGenProcLimit) { + if (result > 7500000000) { + maxThreads = std::min(4, nThreads); + } else if (result > 5500000000) { + maxThreads = std::min(3, nThreads); + } else if (result > 3500000000) { + maxThreads = std::min(2, nThreads); + } else { + maxThreads = std::min(1, nThreads); + } + } + + LogPrintf("ZcashMiner GPU[%d][%d] MemLimit: %s nThreads: %d\n", conf.currentPlatform, conf.currentDevice, std::to_string(result), maxThreads); + + for (int i = 0; i < maxThreads; i++) { + ZcashMiner * miner = new ZcashMiner(1, conf); + sMiners.push_back(miner); + ZcashStratumClient * sc = new ZcashStratumClient{ + miner, host, port, + GetArg("-user", "x"), + GetArg("-password", "x"), + 0, 0 + }; + sClients.push_back(sc); + + miner->onSolutionFound([&](const EquihashSolution& solution) { + return sc->submit(&solution); + }); + + scSig = sc; + signal(SIGINT, stratum_sigint_handler); + } + + } else { + LogPrintf("ZcashMiner ERROR, No OpenCL devices found!\n"); + } + + } + + } else { + for (int i = 0; i < nThreads; i++) { + ZcashMiner * miner = new ZcashMiner(1, conf); + sMiners.push_back(miner); + ZcashStratumClient * sc = new ZcashStratumClient{ + miner, host, port, + GetArg("-user", "x"), + GetArg("-password", "x"), + 0, 0 + }; + sClients.push_back(sc); + + miner->onSolutionFound([&](const EquihashSolution& solution) { + return sc->submit(&solution); + }); + + scSig = sc; + signal(SIGINT, stratum_sigint_handler); + } + } + + while(true) { + + /*for(auto& sc : sClients) + if(!sc.isRunning()) + break;*/ - while(sc.isRunning()) { MilliSleep(1000); } } else { From 8d5d4789bf334acb79731a265824a2dde8ef9b83 Mon Sep 17 00:00:00 2001 From: Omar Alvarez Date: Wed, 2 Nov 2016 10:03:58 +0100 Subject: [PATCH 2/2] Multi-gpu strategy change --- src/libstratum/ZcashStratum.cpp | 97 ++++++++++++++++++- src/standaloneminer.cpp | 164 ++++---------------------------- 2 files changed, 110 insertions(+), 151 deletions(-) diff --git a/src/libstratum/ZcashStratum.cpp b/src/libstratum/ZcashStratum.cpp index 519e3be..bec659e 100644 --- a/src/libstratum/ZcashStratum.cpp +++ b/src/libstratum/ZcashStratum.cpp @@ -298,9 +298,100 @@ void ZcashMiner::start() } minerThreads = new boost::thread_group(); - for (int i = 0; i < nThreads; i++) { - minerThreads->create_thread(boost::bind(&ZcashMinerThread, this, nThreads, i, conf)); - } + + // If using GPU + if(conf.useGPU) { + + conf.currentPlatform = 0; + conf.currentDevice = conf.selGPU; + + std::vector platforms = cl_zogminer::getPlatforms(); + + // use all available GPUs + if(conf.allGPU) { + + int devicesFound = 0; + unsigned numPlatforms = platforms.size(); + + for(unsigned platform = 0; platform < numPlatforms; ++platform) { + + std::vector devices = cl_zogminer::getDevices(platforms, platform); + unsigned noDevices = devices.size(); + devicesFound += noDevices; + for(unsigned device = 0; device < noDevices; ++device) { + + conf.currentPlatform = platform; + conf.currentDevice = device; + + cl_ulong result; + devices[device].getInfo(CL_DEVICE_GLOBAL_MEM_SIZE, &result); + + int maxThreads = nThreads; + if (!conf.forceGenProcLimit) { + if (result > 7500000000) { + maxThreads = std::min(4, nThreads); + } else if (result > 5500000000) { + maxThreads = std::min(3, nThreads); + } else if (result > 3500000000) { + maxThreads = std::min(2, nThreads); + } else { + maxThreads = std::min(1, nThreads); + } + } + + LogPrintf("ZcashMiner GPU[%d][%d] MemLimit: %s nThreads: %d\n", platform, device, std::to_string(result), maxThreads); + + for (int i = 0; i < maxThreads; i++) + minerThreads->create_thread(boost::bind(&ZcashMinerThread, this, nThreads, i, conf)); + + } + } + + if (devicesFound <= 0) { + LogPrintf("ZcashMiner ERROR, No OpenCL devices found!\n"); + } + + } else { + + // mine on specified GPU device + std::vector devices = cl_zogminer::getDevices(platforms, conf.currentPlatform); + + if (devices.size() > conf.currentDevice) { + + cl_ulong result; + devices[conf.currentDevice].getInfo(CL_DEVICE_GLOBAL_MEM_SIZE, &result); + + int maxThreads = nThreads; + if (!conf.forceGenProcLimit) { + if (result > 7500000000) { + maxThreads = std::min(4, nThreads); + } else if (result > 5500000000) { + maxThreads = std::min(3, nThreads); + } else if (result > 3500000000) { + maxThreads = std::min(2, nThreads); + } else { + maxThreads = std::min(1, nThreads); + } + } + + LogPrintf("ZcashMiner GPU[%d][%d] MemLimit: %s nThreads: %d\n", conf.currentPlatform, conf.currentDevice, std::to_string(result), maxThreads); + + for (int i = 0; i < maxThreads; i++) + minerThreads->create_thread(boost::bind(&ZcashMinerThread, this, nThreads, i, conf)); + + } else { + LogPrintf("ZcashMiner ERROR, No OpenCL devices found!\n"); + } + + } + + } else { + + for (int i = 0; i < nThreads; i++) + minerThreads->create_thread(boost::bind(&ZcashMinerThread, this, nThreads, i, conf)); + + } + } void ZcashMiner::stop() diff --git a/src/standaloneminer.cpp b/src/standaloneminer.cpp index 5dfe201..7be260a 100644 --- a/src/standaloneminer.cpp +++ b/src/standaloneminer.cpp @@ -293,154 +293,22 @@ int main(int argc, char* argv[]) return false; } - std::vector sClients; - std::vector sMiners; - - // If using GPU - if(conf.useGPU) { - - conf.currentPlatform = 0; - conf.currentDevice = conf.selGPU; - - std::vector platforms = cl_zogminer::getPlatforms(); - - // use all available GPUs - if(conf.allGPU) { - - int devicesFound = 0; - unsigned numPlatforms = platforms.size(); - - for(unsigned platform = 0; platform < numPlatforms; ++platform) { - - std::vector devices = cl_zogminer::getDevices(platforms, platform); - unsigned noDevices = devices.size(); - devicesFound += noDevices; - for(unsigned device = 0; device < noDevices; ++device) { - - conf.currentPlatform = platform; - conf.currentDevice = device; - - cl_ulong result; - devices[device].getInfo(CL_DEVICE_GLOBAL_MEM_SIZE, &result); - - int maxThreads = nThreads; - if (!conf.forceGenProcLimit) { - if (result > 7500000000) { - maxThreads = std::min(4, nThreads); - } else if (result > 5500000000) { - maxThreads = std::min(3, nThreads); - } else if (result > 3500000000) { - maxThreads = std::min(2, nThreads); - } else { - maxThreads = std::min(1, nThreads); - } - } - - LogPrintf("ZcashMiner GPU[%d][%d] MemLimit: %s nThreads: %d\n", platform, device, std::to_string(result), maxThreads); - - for (int i = 0; i < maxThreads; i++) { - ZcashMiner * miner = new ZcashMiner(1, conf); - sMiners.push_back(miner); - ZcashStratumClient * sc = new ZcashStratumClient{ - miner, host, port, - GetArg("-user", "x"), - GetArg("-password", "x"), - 0, 0 - }; - sClients.push_back(sc); - - miner->onSolutionFound([&](const EquihashSolution& solution) { - return sc->submit(&solution); - }); - - scSig = sc; - signal(SIGINT, stratum_sigint_handler); - } - - } - } - - if (devicesFound <= 0) { - LogPrintf("ZcashMiner ERROR, No OpenCL devices found!\n"); - } - - } else { - - // mine on specified GPU device - std::vector devices = cl_zogminer::getDevices(platforms, conf.currentPlatform); - - if (devices.size() > conf.currentDevice) { - - cl_ulong result; - devices[conf.currentDevice].getInfo(CL_DEVICE_GLOBAL_MEM_SIZE, &result); - - int maxThreads = nThreads; - if (!conf.forceGenProcLimit) { - if (result > 7500000000) { - maxThreads = std::min(4, nThreads); - } else if (result > 5500000000) { - maxThreads = std::min(3, nThreads); - } else if (result > 3500000000) { - maxThreads = std::min(2, nThreads); - } else { - maxThreads = std::min(1, nThreads); - } - } - - LogPrintf("ZcashMiner GPU[%d][%d] MemLimit: %s nThreads: %d\n", conf.currentPlatform, conf.currentDevice, std::to_string(result), maxThreads); - - for (int i = 0; i < maxThreads; i++) { - ZcashMiner * miner = new ZcashMiner(1, conf); - sMiners.push_back(miner); - ZcashStratumClient * sc = new ZcashStratumClient{ - miner, host, port, - GetArg("-user", "x"), - GetArg("-password", "x"), - 0, 0 - }; - sClients.push_back(sc); - - miner->onSolutionFound([&](const EquihashSolution& solution) { - return sc->submit(&solution); - }); - - scSig = sc; - signal(SIGINT, stratum_sigint_handler); - } - - } else { - LogPrintf("ZcashMiner ERROR, No OpenCL devices found!\n"); - } - - } - - } else { - for (int i = 0; i < nThreads; i++) { - ZcashMiner * miner = new ZcashMiner(1, conf); - sMiners.push_back(miner); - ZcashStratumClient * sc = new ZcashStratumClient{ - miner, host, port, - GetArg("-user", "x"), - GetArg("-password", "x"), - 0, 0 - }; - sClients.push_back(sc); - - miner->onSolutionFound([&](const EquihashSolution& solution) { - return sc->submit(&solution); - }); - - scSig = sc; - signal(SIGINT, stratum_sigint_handler); - } - } - - while(true) { - - /*for(auto& sc : sClients) - if(!sc.isRunning()) - break;*/ - + ZcashMiner miner(GetArg("-genproclimit", 1), conf); + ZcashStratumClient sc { + &miner, host, port, + GetArg("-user", "x"), + GetArg("-password", "x"), + 0, 0 + }; + + miner.onSolutionFound([&](const EquihashSolution& solution) { + return sc.submit(&solution); + }); + + scSig = ≻ + signal(SIGINT, stratum_sigint_handler); + + while(sc.isRunning()) { MilliSleep(1000); } } else {