From 9e52ca3205bf29e2ae0d4358d8a73791373e50e5 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Thu, 11 Aug 2016 00:45:31 +1200 Subject: [PATCH] Measure multithreaded solveequihash time per-thread --- src/wallet/rpcwallet.cpp | 9 ++--- src/zcbenchmarks.cpp | 76 ++++++++++++++++++++++++---------------- src/zcbenchmarks.h | 4 +-- 3 files changed, 52 insertions(+), 37 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 5cf4202a..0fc34966 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2447,10 +2447,11 @@ Value zc_benchmark(const json_spirit::Array& params, bool fHelp) sample_times.push_back(benchmark_verify_joinsplit(samplejoinsplit)); } else if (benchmarktype == "solveequihash") { if (params.size() < 3) { - sample_times.push_back(benchmark_solve_equihash(true)); + sample_times.push_back(benchmark_solve_equihash()); } else { int nThreads = params[2].get_int(); - sample_times.push_back(benchmark_solve_equihash_threaded(nThreads)); + std::vector vals = benchmark_solve_equihash_threaded(nThreads); + sample_times.insert(sample_times.end(), vals.begin(), vals.end()); } } else if (benchmarktype == "verifyequihash") { sample_times.push_back(benchmark_verify_equihash()); @@ -2462,9 +2463,9 @@ Value zc_benchmark(const json_spirit::Array& params, bool fHelp) } Array results; - for (int i = 0; i < samplecount; i++) { + for (auto time : sample_times) { Object result; - result.push_back(Pair("runningtime", sample_times.at(i))); + result.push_back(Pair("runningtime", time)); results.push_back(result); } diff --git a/src/zcbenchmarks.cpp b/src/zcbenchmarks.cpp index 0bea9b09..3a11095c 100644 --- a/src/zcbenchmarks.cpp +++ b/src/zcbenchmarks.cpp @@ -1,6 +1,8 @@ +#include +#include #include #include -#include + #include "coins.h" #include "util.h" #include "init.h" @@ -24,14 +26,12 @@ using namespace libzcash; -struct timeval tv_start; - -void timer_start() +void timer_start(timeval &tv_start) { gettimeofday(&tv_start, 0); } -double timer_stop() +double timer_stop(timeval &tv_start) { double elapsed; struct timeval tv_end; @@ -43,9 +43,10 @@ double timer_stop() double benchmark_sleep() { - timer_start(); + struct timeval tv_start; + timer_start(tv_start); sleep(1); - return timer_stop(); + return timer_stop(tv_start); } double benchmark_parameter_loading() @@ -54,7 +55,8 @@ double benchmark_parameter_loading() boost::filesystem::path pk_path = ZC_GetParamsDir() / "z9-proving.key"; boost::filesystem::path vk_path = ZC_GetParamsDir() / "z9-verifying.key"; - timer_start(); + struct timeval tv_start; + timer_start(tv_start); auto newParams = ZCJoinSplit::Unopened(); @@ -62,7 +64,7 @@ double benchmark_parameter_loading() newParams->setProvingKeyPath(pk_path.string()); newParams->loadProvingKey(); - double ret = timer_stop(); + double ret = timer_stop(tv_start); delete newParams; @@ -76,7 +78,8 @@ double benchmark_create_joinsplit() /* Get the anchor of an empty commitment tree. */ uint256 anchor = ZCIncrementalMerkleTree().root(); - timer_start(); + struct timeval tv_start; + timer_start(tv_start); JSDescription jsdesc(*pzcashParams, pubKeyHash, anchor, @@ -84,7 +87,7 @@ double benchmark_create_joinsplit() {JSOutput(), JSOutput()}, 0, 0); - double ret = timer_stop(); + double ret = timer_stop(tv_start); assert(jsdesc.Verify(*pzcashParams, pubKeyHash)); return ret; @@ -92,13 +95,14 @@ double benchmark_create_joinsplit() double benchmark_verify_joinsplit(const JSDescription &joinsplit) { - timer_start(); + struct timeval tv_start; + timer_start(tv_start); uint256 pubKeyHash; joinsplit.Verify(*pzcashParams, pubKeyHash); - return timer_stop(); + return timer_stop(tv_start); } -double benchmark_solve_equihash(bool time) +double benchmark_solve_equihash() { CBlock pblock; CEquihashInput I{pblock}; @@ -117,25 +121,33 @@ double benchmark_solve_equihash(bool time) nonce.begin(), nonce.size()); - if (time) - timer_start(); + struct timeval tv_start; + timer_start(tv_start); std::set> solns; EhOptimisedSolveUncancellable(n, k, eh_state, [](std::vector soln) { return false; }); - if (time) - return timer_stop(); - else - return 0; + return timer_stop(tv_start); } -double benchmark_solve_equihash_threaded(int nThreads) +std::vector benchmark_solve_equihash_threaded(int nThreads) { - boost::thread_group solverThreads; - timer_start(); - for (int i = 0; i < nThreads; i++) - solverThreads.create_thread(boost::bind(&benchmark_solve_equihash, false)); - solverThreads.join_all(); - return timer_stop(); + std::vector ret; + std::vector> tasks; + std::vector threads; + for (int i = 0; i < nThreads; i++) { + std::packaged_task task(&benchmark_solve_equihash); + tasks.emplace_back(task.get_future()); + threads.emplace_back(std::move(task)); + } + std::future_status status; + for (auto it = tasks.begin(); it != tasks.end(); it++) { + it->wait(); + ret.push_back(it->get()); + } + for (auto it = threads.begin(); it != threads.end(); it++) { + it->join(); + } + return ret; } double benchmark_verify_equihash() @@ -143,9 +155,10 @@ double benchmark_verify_equihash() CChainParams params = Params(CBaseChainParams::MAIN); CBlock genesis = Params(CBaseChainParams::MAIN).GenesisBlock(); CBlockHeader genesis_header = genesis.GetBlockHeader(); - timer_start(); + struct timeval tv_start; + timer_start(tv_start); CheckEquihashSolution(&genesis_header, params); - return timer_stop(); + return timer_stop(tv_start); } double benchmark_large_tx() @@ -197,7 +210,8 @@ double benchmark_large_tx() CTransaction final_spending_tx(spending_tx); // Benchmark signature verification costs: - timer_start(); + struct timeval tv_start; + timer_start(tv_start); for (size_t i = 0; i < NUM_INPUTS; i++) { ScriptError serror = SCRIPT_ERR_OK; assert(VerifyScript(final_spending_tx.vin[i].scriptSig, @@ -206,6 +220,6 @@ double benchmark_large_tx() TransactionSignatureChecker(&final_spending_tx, i), &serror)); } - return timer_stop(); + return timer_stop(tv_start); } diff --git a/src/zcbenchmarks.h b/src/zcbenchmarks.h index c11f0c9f..b81d4a70 100644 --- a/src/zcbenchmarks.h +++ b/src/zcbenchmarks.h @@ -7,8 +7,8 @@ extern double benchmark_sleep(); extern double benchmark_parameter_loading(); extern double benchmark_create_joinsplit(); -extern double benchmark_solve_equihash(bool time); -extern double benchmark_solve_equihash_threaded(int nThreads); +extern double benchmark_solve_equihash(); +extern std::vector benchmark_solve_equihash_threaded(int nThreads); extern double benchmark_verify_joinsplit(const JSDescription &joinsplit); extern double benchmark_verify_equihash(); extern double benchmark_large_tx();