diff --git a/CMakeLists.txt b/CMakeLists.txt index 85a2db5e3..b11639609 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 2.8.12) set(PROJECT_VERSION "0.9.41") -set(GENOIL_VERSION "1.1.2") +set(GENOIL_VERSION "1.1.3") if (${CMAKE_VERSION} VERSION_GREATER 3.0) cmake_policy(SET CMP0042 OLD) # fix MACOSX_RPATH cmake_policy(SET CMP0048 NEW) # allow VERSION argument in project() diff --git a/ethminer/MinerAux.h b/ethminer/MinerAux.h index b84581fe7..3423594c1 100644 --- a/ethminer/MinerAux.h +++ b/ethminer/MinerAux.h @@ -325,6 +325,18 @@ public: else if (arg == "--cuda-streams" && i + 1 < argc) m_numStreams = stol(argv[++i]); #endif + else if ((arg == "-L" || arg == "--dag-load-mode") && i + 1 < argc) + { + string mode = argv[++i]; + if (mode == "parallel") m_dagLoadMode = DAG_LOAD_MODE_PARALLEL; + else if (mode == "sequential") m_dagLoadMode = DAG_LOAD_MODE_SEQUENTIAL; + else + { + cerr << "Bad " << arg << " option: " << argv[i] << endl; + BOOST_THROW_EXCEPTION(BadArgument()); + } + } + /* else if (arg == "--phone-home" && i + 1 < argc) { string m = argv[++i]; @@ -338,6 +350,7 @@ public: BOOST_THROW_EXCEPTION(BadArgument()); } } + */ else if (arg == "--benchmark-warmup" && i + 1 < argc) try { m_benchmarkWarmup = stol(argv[++i]); @@ -378,6 +391,7 @@ public: { m_minerType = MinerType::Mixed; } + /* else if (arg == "--current-block" && i + 1 < argc) m_currentBlock = stol(argv[++i]); else if ((arg == "-w" || arg == "--check-pow") && i + 4 < argc) @@ -417,6 +431,7 @@ public: BOOST_THROW_EXCEPTION(BadArgument()); } } + */ else if (arg == "-M" || arg == "--benchmark") { mode = OperationMode::Benchmark; @@ -495,7 +510,10 @@ public: } if (m_minerType == MinerType::CPU) - EthashCPUMiner::setNumInstances(m_miningThreads); + { + cout << "CPU mining is no longer supported in this miner. Use -G (opencl) or -U (cuda) flag to select GPU platform." << endl; + exit(0); + } else if (m_minerType == MinerType::CL || m_minerType == MinerType::Mixed) { #if ETH_ETHASHCL || !ETH_TRUE @@ -512,7 +530,8 @@ public: m_openclDevice, m_clAllowCPU, m_extraGPUMemory, - m_currentBlock + 0, + m_dagLoadMode )) exit(1); EthashGPUMiner::setNumInstances(m_miningThreads); @@ -537,7 +556,8 @@ public: m_numStreams, m_extraGPUMemory, m_cudaSchedule, - m_currentBlock + 0, + m_dagLoadMode )) exit(1); #else @@ -545,9 +565,7 @@ public: exit(1); #endif } - if (mode == OperationMode::DAGInit) - doInitDAG(m_initDAG); - else if (mode == OperationMode::Benchmark) + if (mode == OperationMode::Benchmark) doBenchmark(m_minerType, m_phoneHome, m_benchmarkWarmup, m_benchmarkTrial, m_benchmarkTrials); else if (mode == OperationMode::Farm) doFarm(m_minerType, m_activeFarmURL, m_farmRecheckPeriod); @@ -574,14 +592,11 @@ public: << " -O, --userpass Stratum login credentials" << endl << " -FO, --failover-userpass Failover stratum login credentials (optional, will use normal credentials when omitted)" << endl << " --work-timeout reconnect/failover after n seconds of working on the same (stratum) job. Defaults to 180. Don't set lower than max. avg. block time" << endl - << " -SV, --stratum-version Stratum client version. Defaults to 1 (async client). Use 2 to test new synchronous client." + << " -SV, --stratum-version Stratum client version. Defaults to 1 (async client). Use 2 to test new synchronous client." #endif #if ETH_JSONRPC || ETH_STRATUM || !ETH_TRUE << " --farm-recheck Leave n ms between checks for changed work (default: 500). When using stratum, use a high value (i.e. 2000) to get more stable hashrate output" << endl - << " --no-precompute Don't precompute the next epoch's DAG." << endl #endif - << "Ethash verify mode:" << endl - << " -w,--check-pow Check PoW credentials for validity." << endl << endl << "Benchmarking mode:" << endl << " -M [],--benchmark [] Benchmark for mining and exit; Optionally specify block number to benchmark against specific DAG." << endl @@ -590,20 +605,19 @@ public: << " --benchmark-trials Set the duration of warmup for the benchmark tests (default: 5)." << endl << "Simulation mode:" << endl << " -Z [],--simulation [] Mining test mode. Used to validate kernel optimizations. Optionally specify block number." << endl -#if ETH_JSONRPC || !ETH_TRUE - << " --phone-home When benchmarking, publish results (default: off)" << endl -#endif << "Mining configuration:" << endl - << " -C,--cpu When mining, use the CPU." << endl << " -G,--opencl When mining use the GPU via OpenCL." << endl << " -U,--cuda When mining use the GPU via CUDA." << endl + << " -X,--cuda-opencl Use OpenCL + CUDA in a system with mixed AMD/Nvidia cards. May require setting --opencl-platform 1" << endl << " --opencl-platform When mining using -G/--opencl use OpenCL platform n (default: 0)." << endl << " --opencl-device When mining using -G/--opencl use OpenCL device n (default: 0)." << endl << " --opencl-devices <0 1 ..n> Select which OpenCL devices to mine on. Default is to use all" << endl << " -t, --mining-threads Limit number of CPU/GPU miners to n (default: use everything available on selected platform)" << endl << " --allow-opencl-cpu Allows CPU to be considered as an OpenCL device if the OpenCL platform supports it." << endl << " --list-devices List the detected OpenCL/CUDA devices and exit. Should be combined with -G or -U flag" << endl - << " --current-block Let the miner know the current block number at configuration time. Will help determine DAG size and required GPU memory." << endl + << " -L, --dag-load-mode DAG generation mode." << endl + << " parallel - load DAG on all GPUs at the same time (default)" << endl + << " sequential - load DAG on GPUs one after another. Use this when the miner crashes during DAG generation" << endl #if ETH_ETHASHCL || !ETH_TRUE << " --cl-extragpu-mem Set the memory (in MB) you believe your GPU requires for stuff other than mining. default: 0" << endl << " --cl-local-work Set the OpenCL local work size. Default is " << toString(ethash_cl_miner::c_defaultLocalWorkSize) << endl @@ -625,7 +639,6 @@ public: } MinerType minerType() const { return m_minerType; } - bool shouldPrecompute() const { return m_precompute; } private: void doInitDAG(unsigned _n) @@ -979,7 +992,7 @@ private: // this is very ugly, but if Stratum Client V2 tunrs out to be a success, V1 will be completely removed anyway if (m_stratumClientVersion == 1) { - EthStratumClient client(&f, m_minerType, m_farmURL, m_port, m_user, m_pass, m_maxFarmRetries, m_worktimeout, m_precompute); + EthStratumClient client(&f, m_minerType, m_farmURL, m_port, m_user, m_pass, m_maxFarmRetries, m_worktimeout); if (m_farmFailOverURL != "") { if (m_fuser != "") @@ -1054,7 +1067,6 @@ private: /// Operating mode. OperationMode mode; - DAGEraseMode m_eraseMode = DAGEraseMode::None; /// Mining options bool m_running = true; @@ -1080,14 +1092,9 @@ private: unsigned m_numStreams = ethash_cuda_miner::c_defaultNumStreams; unsigned m_cudaSchedule = 4; // sync #endif - uint64_t m_currentBlock = 0; - static char s_dagDir[256]; // default value was 350MB of GPU memory for other stuff (windows system rendering, e.t.c.) unsigned m_extraGPUMemory = 0;// 350000000; don't assume miners run desktops... - - /// DAG initialisation param. - unsigned m_initDAG = 0; - + unsigned m_dagLoadMode = 0; // parallel /// Benchmarking params bool m_phoneHome = false; unsigned m_benchmarkWarmup = 15; @@ -1106,7 +1113,6 @@ private: unsigned m_defaultStratumFarmRecheckPeriod = 2000; bool m_farmRecheckSet = false; int m_worktimeout = 180; - bool m_precompute = true; #if ETH_STRATUM || !ETH_TRUE int m_stratumClientVersion = 1; @@ -1118,5 +1124,3 @@ private: #endif string m_fport = ""; }; - -char MinerCLI::s_dagDir[256] = ""; diff --git a/libethash-cl/ethash_cl_miner.cpp b/libethash-cl/ethash_cl_miner.cpp index 06d512ee0..1c8d9367a 100644 --- a/libethash-cl/ethash_cl_miner.cpp +++ b/libethash-cl/ethash_cl_miner.cpp @@ -205,6 +205,7 @@ bool ethash_cl_miner::configureGPU( s_initialGlobalWorkSize = _globalWorkSize; s_allowCPU = _allowCPU; s_extraRequiredGPUMem = _extraGPUMemory; + // by default let's only consider the DAG of the first epoch uint64_t dagSize = ethash_get_datasize(_currentBlock); uint64_t requiredSize = dagSize + _extraGPUMemory; diff --git a/libethash-cuda/ethash_cuda_miner.cpp b/libethash-cuda/ethash_cuda_miner.cpp index 5f8937ef7..4d231dcda 100644 --- a/libethash-cuda/ethash_cuda_miner.cpp +++ b/libethash-cuda/ethash_cuda_miner.cpp @@ -231,15 +231,12 @@ bool ethash_cuda_miner::init(ethash_light_t _light, uint8_t const* _lightData, u // create buffer for cache hash64_t * light; CUDA_SAFE_CALL(cudaMalloc(reinterpret_cast(&light), _lightSize)); - // copy dag to CPU. + // copy dag cache to CPU. CUDA_SAFE_CALL(cudaMemcpy(reinterpret_cast(light), _lightData, _lightSize, cudaMemcpyHostToDevice)); // create buffer for dag hash128_t * dag; CUDA_SAFE_CALL(cudaMalloc(reinterpret_cast(&dag), dagSize)); - // copy dag to CPU. - //CUDA_SAFE_CALL(cudaMemcpy(reinterpret_cast(dag), _dag, _dagSize, cudaMemcpyHostToDevice)); - // create mining buffers for (unsigned i = 0; i != s_numStreams; ++i) diff --git a/libethash-cuda/ethash_cuda_miner.h b/libethash-cuda/ethash_cuda_miner.h index b2b9f1d60..a05ce5d55 100644 --- a/libethash-cuda/ethash_cuda_miner.h +++ b/libethash-cuda/ethash_cuda_miner.h @@ -34,11 +34,7 @@ public: unsigned _scheduleFlag, uint64_t _currentBlock ); - /*bool init( - uint8_t const* _dag, - uint64_t _dagSize, - unsigned _deviceId = 0 - );*/ + bool init(ethash_light_t _light, uint8_t const* _lightData, uint64_t _lightSize, unsigned _deviceId); void finish(); diff --git a/libethcore/EthashAux.cpp b/libethcore/EthashAux.cpp index 279e2a7f7..d4467f4c3 100644 --- a/libethcore/EthashAux.cpp +++ b/libethcore/EthashAux.cpp @@ -52,6 +52,8 @@ const unsigned EthashProofOfWork::defaultGlobalWorkSizeMultiplier = 4096; // * C const unsigned EthashProofOfWork::defaultMSPerBatch = 0; const EthashProofOfWork::WorkPackage EthashProofOfWork::NullWorkPackage = EthashProofOfWork::WorkPackage(); +//unsigned EthashProofOfWork::s_dagLoadMode = 0; + EthashAux::~EthashAux() { } diff --git a/libethcore/EthashAux.h b/libethcore/EthashAux.h index e1900d775..02d2e58df 100644 --- a/libethcore/EthashAux.h +++ b/libethcore/EthashAux.h @@ -32,6 +32,7 @@ namespace dev namespace eth { + struct DAGChannel: public LogChannel { static const char* name(); static const int verbosity = 1; }; /// Proof of work definition for Ethash. @@ -73,6 +74,7 @@ struct EthashProofOfWork static const unsigned defaultGlobalWorkSizeMultiplier; /// Default value of the milliseconds per global work size (per batch) static const unsigned defaultMSPerBatch; + }; enum class DAGEraseMode diff --git a/libethcore/EthashCUDAMiner.cpp b/libethcore/EthashCUDAMiner.cpp index 17cbedf6b..ea75ac2b8 100644 --- a/libethcore/EthashCUDAMiner.cpp +++ b/libethcore/EthashCUDAMiner.cpp @@ -144,6 +144,13 @@ void EthashCUDAMiner::workLoop() cnote << "set work; seed: " << "#" + w.seedHash.hex().substr(0, 8) + ", target: " << "#" + w.boundary.hex().substr(0, 16); if (!m_miner || m_minerSeed != w.seedHash) { + if (s_dagLoadMode == DAG_LOAD_MODE_SEQUENTIAL) + { + while (s_dagLoadIndex < index()) { + this_thread::sleep_for(chrono::seconds(1)); + } + } + cnote << "Initialising miner..."; m_minerSeed = w.seedHash; @@ -158,6 +165,7 @@ void EthashCUDAMiner::workLoop() bytesConstRef lightData = light->data(); m_miner->init(light->light, lightData.data(), lightData.size(), device); + s_dagLoadIndex++; } uint64_t upper64OfBoundary = (uint64_t)(u64)((u256)w.boundary >> 192); @@ -198,17 +206,13 @@ bool EthashCUDAMiner::configureGPU( unsigned _numStreams, unsigned _extraGPUMemory, unsigned _scheduleFlag, - uint64_t _currentBlock + uint64_t _currentBlock, + unsigned _dagLoadMode ) { + s_dagLoadMode = _dagLoadMode; _blockSize = ((_blockSize + 7) / 8) * 8; - /* - if (_blockSize != 32 && _blockSize != 64 && _blockSize != 128) - { - cout << "Given localWorkSize of " << toString(_blockSize) << "is invalid. Must be either 32,64 or 128" << endl; - return false; - } - */ + if (!ethash_cuda_miner::configureGPU( s_devices, _blockSize, diff --git a/libethcore/EthashCUDAMiner.h b/libethcore/EthashCUDAMiner.h index 3c1dae3dd..911b8f460 100644 --- a/libethcore/EthashCUDAMiner.h +++ b/libethcore/EthashCUDAMiner.h @@ -53,7 +53,8 @@ namespace eth unsigned _numStreams, unsigned _extraGPUMemory, unsigned _scheduleFlag, - uint64_t _currentBlock + uint64_t _currentBlock, + unsigned _dagLoadMode ); static void setNumInstances(unsigned _instances) { @@ -84,6 +85,7 @@ namespace eth static unsigned s_deviceId; static unsigned s_numInstances; static int s_devices[16]; + }; } } diff --git a/libethcore/EthashGPUMiner.cpp b/libethcore/EthashGPUMiner.cpp index 2fa44fa61..2346b718a 100644 --- a/libethcore/EthashGPUMiner.cpp +++ b/libethcore/EthashGPUMiner.cpp @@ -142,6 +142,13 @@ void EthashGPUMiner::workLoop() cnote << "set work; seed: " << "#" + w.seedHash.hex().substr(0, 8) + ", target: " << "#" + w.boundary.hex().substr(0, 16); if (!m_miner || m_minerSeed != w.seedHash) { + if (s_dagLoadMode == DAG_LOAD_MODE_SEQUENTIAL) + { + while (s_dagLoadIndex < index()) { + this_thread::sleep_for(chrono::seconds(1)); + } + } + cnote << "Initialising miner..."; m_minerSeed = w.seedHash; @@ -172,6 +179,7 @@ void EthashGPUMiner::workLoop() bytesConstRef lightData = light->data(); m_miner->init(light->light, lightData.data(), lightData.size(), s_platformId, device); + s_dagLoadIndex++; } uint64_t upper64OfBoundary = (uint64_t)(u64)((u256)w.boundary >> 192); @@ -213,27 +221,25 @@ bool EthashGPUMiner::configureGPU( unsigned _deviceId, bool _allowCPU, unsigned _extraGPUMemory, - uint64_t _currentBlock + uint64_t _currentBlock, + unsigned _dagLoadMode ) { + s_dagLoadMode = _dagLoadMode; + s_platformId = _platformId; s_deviceId = _deviceId; _localWorkSize = ((_localWorkSize + 7) / 8) * 8; - /* - if (_localWorkSize != 32 && _localWorkSize != 64 && _localWorkSize != 128 && _localWorkSize != 256) - { - cout << "Given localWorkSize of " << toString(_localWorkSize) << "is invalid. Must be either 32,64,128 or 256" << endl; - return false; - } - */ + if (!ethash_cl_miner::configureGPU( _platformId, _localWorkSize, _globalWorkSizeMultiplier * _localWorkSize, _allowCPU, _extraGPUMemory, - _currentBlock) + _currentBlock + ) ) { cout << "No GPU device with sufficient memory was found. Can't GPU mine. Remove the -G argument" << endl; diff --git a/libethcore/EthashGPUMiner.h b/libethcore/EthashGPUMiner.h index 1db025b18..847799775 100644 --- a/libethcore/EthashGPUMiner.h +++ b/libethcore/EthashGPUMiner.h @@ -52,7 +52,8 @@ public: unsigned _deviceId, bool _allowCPU, unsigned _extraGPUMemory, - uint64_t _currentBlock + uint64_t _currentBlock, + unsigned _dagLoadMode ); static void setNumInstances(unsigned _instances) { s_numInstances = std::min(_instances, getNumDevices()); } static void setDevices(unsigned * _devices, unsigned _selectedDeviceCount) @@ -81,6 +82,7 @@ private: static unsigned s_deviceId; static unsigned s_numInstances; static int s_devices[16]; + }; } diff --git a/libethcore/Miner.cpp b/libethcore/Miner.cpp index e69de29bb..e0f7bc31f 100644 --- a/libethcore/Miner.cpp +++ b/libethcore/Miner.cpp @@ -0,0 +1,10 @@ +#include "Miner.h" +#include "EthashAux.h" + +using namespace dev; +using namespace eth; + +unsigned dev::eth::GenericMiner::s_dagLoadMode = 0; +unsigned dev::eth::GenericMiner::s_dagLoadIndex = 0; + + diff --git a/libethcore/Miner.h b/libethcore/Miner.h index 2bf935ed4..1c8d00998 100644 --- a/libethcore/Miner.h +++ b/libethcore/Miner.h @@ -35,6 +35,11 @@ #define MINER_WAIT_STATE_WORK 1 #define MINER_WAIT_STATE_DAG 2 + +#define DAG_LOAD_MODE_PARALLEL 0 +#define DAG_LOAD_MODE_SEQUENTIAL 1 + + using namespace std; typedef struct { @@ -102,6 +107,7 @@ inline std::ostream& operator<<(std::ostream& os, SolutionStats s) template class GenericMiner; + /** * @brief Class for hosting one or more Miners. * @warning Must be implemented in a threadsafe manner since it will be called from multiple @@ -173,6 +179,7 @@ public: protected: + // REQUIRED TO BE REIMPLEMENTED BY A SUBCLASS: /** @@ -210,6 +217,8 @@ protected: void accumulateHashes(unsigned _n) { m_hashCount += _n; } + static unsigned s_dagLoadMode; + static unsigned s_dagLoadIndex; private: FarmFace* m_farm = nullptr; unsigned m_index; @@ -218,6 +227,9 @@ private: WorkPackage m_work; mutable Mutex x_work; + + + bool m_dagLoaded = false; }; } diff --git a/libstratum/EthStratumClient.cpp b/libstratum/EthStratumClient.cpp index 137e8faa2..029c15754 100644 --- a/libstratum/EthStratumClient.cpp +++ b/libstratum/EthStratumClient.cpp @@ -4,7 +4,7 @@ using boost::asio::ip::tcp; -EthStratumClient::EthStratumClient(GenericFarm * f, MinerType m, string const & host, string const & port, string const & user, string const & pass, int const & retries, int const & worktimeout, bool const & precompute) +EthStratumClient::EthStratumClient(GenericFarm * f, MinerType m, string const & host, string const & port, string const & user, string const & pass, int const & retries, int const & worktimeout) : m_socket(m_io_service) { m_minerType = m; @@ -17,7 +17,6 @@ EthStratumClient::EthStratumClient(GenericFarm * f, MinerType m_authorized = false; m_connected = false; - m_precompute = precompute; m_pending = 0; m_maxRetries = retries; m_worktimeout = worktimeout; diff --git a/libstratum/EthStratumClient.h b/libstratum/EthStratumClient.h index 8ca98a248..c91493d37 100644 --- a/libstratum/EthStratumClient.h +++ b/libstratum/EthStratumClient.h @@ -21,7 +21,7 @@ using namespace dev::eth; class EthStratumClient { public: - EthStratumClient(GenericFarm * f, MinerType m, string const & host, string const & port, string const & user, string const & pass, int const & retries, int const & worktimeout, bool const & precompute); + EthStratumClient(GenericFarm * f, MinerType m, string const & host, string const & port, string const & user, string const & pass, int const & retries, int const & worktimeout); ~EthStratumClient(); void setFailover(string const & host, string const & port);