123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- /*
- This file is part of cpp-ethereum.
- cpp-ethereum is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- cpp-ethereum is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
- */
- /** @file EthashCPUMiner.cpp
- * @author Gav Wood <i@gavwood.com>
- * @date 2014
- *
- * Determines the PoW algorithm.
- */
- #include "EthashCPUMiner.h"
- #include <thread>
- #include <chrono>
- #include <boost/algorithm/string.hpp>
- #include <random>
- #if ETH_CPUID
- #define HAVE_STDINT_H
- #include <libcpuid/libcpuid.h>
- #endif // ETH_CPUID
- using namespace std;
- using namespace dev;
- using namespace eth;
- unsigned EthashCPUMiner::s_numInstances = 0;
- #if ETH_CPUID
- static string jsonEncode(map<string, string> const& _m)
- {
- string ret = "{";
- for (auto const& i: _m)
- {
- string k = boost::replace_all_copy(boost::replace_all_copy(i.first, "\\", "\\\\"), "'", "\\'");
- string v = boost::replace_all_copy(boost::replace_all_copy(i.second, "\\", "\\\\"), "'", "\\'");
- if (ret.size() > 1)
- ret += ", ";
- ret += "\"" + k + "\":\"" + v + "\"";
- }
- return ret + "}";
- }
- #endif // ETH_CPUID
- EthashCPUMiner::EthashCPUMiner(GenericMiner<EthashProofOfWork>::ConstructionInfo const& _ci):
- GenericMiner<EthashProofOfWork>(_ci), Worker("miner" + toString(index()))
- {
- }
- EthashCPUMiner::~EthashCPUMiner()
- {
- }
- void EthashCPUMiner::kickOff()
- {
- stopWorking();
- startWorking();
- }
- void EthashCPUMiner::pause()
- {
- stopWorking();
- }
- void EthashCPUMiner::workLoop()
- {
- auto tid = std::this_thread::get_id();
- static std::mt19937_64 s_eng((utcTime() + std::hash<decltype(tid)>()(tid)));
- uint64_t tryNonce = s_eng();
- ethash_return_value ethashReturn;
- WorkPackage w = work();
- EthashAux::FullType dag;
- while (!shouldStop() && !dag)
- {
- while (!shouldStop() && EthashAux::computeFull(w.seedHash, true) != 100)
- this_thread::sleep_for(chrono::milliseconds(500));
- dag = EthashAux::full(w.seedHash, false);
- }
- h256 boundary = w.boundary;
- unsigned hashCount = 1;
- for (; !shouldStop(); tryNonce++, hashCount++)
- {
- ethashReturn = ethash_full_compute(dag->full, *(ethash_h256_t*)w.headerHash.data(), tryNonce);
- h256 value = h256((uint8_t*)ðashReturn.result, h256::ConstructFromPointer);
- if (value <= boundary && submitProof(EthashProofOfWork::Solution{(h64)(u64)tryNonce, h256((uint8_t*)ðashReturn.mix_hash, h256::ConstructFromPointer)}))
- break;
- if (!(hashCount % 100))
- accumulateHashes(100);
- }
- }
- std::string EthashCPUMiner::platformInfo()
- {
- string baseline = toString(std::thread::hardware_concurrency()) + "-thread CPU";
- #if ETH_CPUID
- if (!cpuid_present())
- return baseline;
- struct cpu_raw_data_t raw;
- struct cpu_id_t data;
- if (cpuid_get_raw_data(&raw) < 0)
- return baseline;
- if (cpu_identify(&raw, &data) < 0)
- return baseline;
- map<string, string> m;
- m["vendor"] = data.vendor_str;
- m["codename"] = data.cpu_codename;
- m["brand"] = data.brand_str;
- m["L1 cache"] = toString(data.l1_data_cache);
- m["L2 cache"] = toString(data.l2_cache);
- m["L3 cache"] = toString(data.l3_cache);
- m["cores"] = toString(data.num_cores);
- m["threads"] = toString(data.num_logical_cpus);
- m["clocknominal"] = toString(cpu_clock_by_os());
- m["clocktested"] = toString(cpu_clock_measure(200, 0));
- /*
- printf(" MMX : %s\n", data.flags[CPU_FEATURE_MMX] ? "present" : "absent");
- printf(" MMX-extended: %s\n", data.flags[CPU_FEATURE_MMXEXT] ? "present" : "absent");
- printf(" SSE : %s\n", data.flags[CPU_FEATURE_SSE] ? "present" : "absent");
- printf(" SSE2 : %s\n", data.flags[CPU_FEATURE_SSE2] ? "present" : "absent");
- printf(" 3DNow! : %s\n", data.flags[CPU_FEATURE_3DNOW] ? "present" : "absent");
- */
- return jsonEncode(m);
- #else
- return baseline;
- #endif // ETH_CPUID
- }
|