Measure multithreaded solveequihash time per-thread

This commit is contained in:
Jack Grigg
2016-08-11 00:45:31 +12:00
parent 80259d4b4f
commit 9e52ca3205
3 changed files with 52 additions and 37 deletions

View File

@@ -2447,10 +2447,11 @@ Value zc_benchmark(const json_spirit::Array& params, bool fHelp)
sample_times.push_back(benchmark_verify_joinsplit(samplejoinsplit)); sample_times.push_back(benchmark_verify_joinsplit(samplejoinsplit));
} else if (benchmarktype == "solveequihash") { } else if (benchmarktype == "solveequihash") {
if (params.size() < 3) { if (params.size() < 3) {
sample_times.push_back(benchmark_solve_equihash(true)); sample_times.push_back(benchmark_solve_equihash());
} else { } else {
int nThreads = params[2].get_int(); int nThreads = params[2].get_int();
sample_times.push_back(benchmark_solve_equihash_threaded(nThreads)); std::vector<double> vals = benchmark_solve_equihash_threaded(nThreads);
sample_times.insert(sample_times.end(), vals.begin(), vals.end());
} }
} else if (benchmarktype == "verifyequihash") { } else if (benchmarktype == "verifyequihash") {
sample_times.push_back(benchmark_verify_equihash()); sample_times.push_back(benchmark_verify_equihash());
@@ -2462,9 +2463,9 @@ Value zc_benchmark(const json_spirit::Array& params, bool fHelp)
} }
Array results; Array results;
for (int i = 0; i < samplecount; i++) { for (auto time : sample_times) {
Object result; Object result;
result.push_back(Pair("runningtime", sample_times.at(i))); result.push_back(Pair("runningtime", time));
results.push_back(result); results.push_back(result);
} }

View File

@@ -1,6 +1,8 @@
#include <future>
#include <thread>
#include <unistd.h> #include <unistd.h>
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <boost/thread.hpp>
#include "coins.h" #include "coins.h"
#include "util.h" #include "util.h"
#include "init.h" #include "init.h"
@@ -24,14 +26,12 @@
using namespace libzcash; using namespace libzcash;
struct timeval tv_start; void timer_start(timeval &tv_start)
void timer_start()
{ {
gettimeofday(&tv_start, 0); gettimeofday(&tv_start, 0);
} }
double timer_stop() double timer_stop(timeval &tv_start)
{ {
double elapsed; double elapsed;
struct timeval tv_end; struct timeval tv_end;
@@ -43,9 +43,10 @@ double timer_stop()
double benchmark_sleep() double benchmark_sleep()
{ {
timer_start(); struct timeval tv_start;
timer_start(tv_start);
sleep(1); sleep(1);
return timer_stop(); return timer_stop(tv_start);
} }
double benchmark_parameter_loading() 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 pk_path = ZC_GetParamsDir() / "z9-proving.key";
boost::filesystem::path vk_path = ZC_GetParamsDir() / "z9-verifying.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(); auto newParams = ZCJoinSplit::Unopened();
@@ -62,7 +64,7 @@ double benchmark_parameter_loading()
newParams->setProvingKeyPath(pk_path.string()); newParams->setProvingKeyPath(pk_path.string());
newParams->loadProvingKey(); newParams->loadProvingKey();
double ret = timer_stop(); double ret = timer_stop(tv_start);
delete newParams; delete newParams;
@@ -76,7 +78,8 @@ double benchmark_create_joinsplit()
/* Get the anchor of an empty commitment tree. */ /* Get the anchor of an empty commitment tree. */
uint256 anchor = ZCIncrementalMerkleTree().root(); uint256 anchor = ZCIncrementalMerkleTree().root();
timer_start(); struct timeval tv_start;
timer_start(tv_start);
JSDescription jsdesc(*pzcashParams, JSDescription jsdesc(*pzcashParams,
pubKeyHash, pubKeyHash,
anchor, anchor,
@@ -84,7 +87,7 @@ double benchmark_create_joinsplit()
{JSOutput(), JSOutput()}, {JSOutput(), JSOutput()},
0, 0,
0); 0);
double ret = timer_stop(); double ret = timer_stop(tv_start);
assert(jsdesc.Verify(*pzcashParams, pubKeyHash)); assert(jsdesc.Verify(*pzcashParams, pubKeyHash));
return ret; return ret;
@@ -92,13 +95,14 @@ double benchmark_create_joinsplit()
double benchmark_verify_joinsplit(const JSDescription &joinsplit) double benchmark_verify_joinsplit(const JSDescription &joinsplit)
{ {
timer_start(); struct timeval tv_start;
timer_start(tv_start);
uint256 pubKeyHash; uint256 pubKeyHash;
joinsplit.Verify(*pzcashParams, 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; CBlock pblock;
CEquihashInput I{pblock}; CEquihashInput I{pblock};
@@ -117,25 +121,33 @@ double benchmark_solve_equihash(bool time)
nonce.begin(), nonce.begin(),
nonce.size()); nonce.size());
if (time) struct timeval tv_start;
timer_start(); timer_start(tv_start);
std::set<std::vector<unsigned int>> solns; std::set<std::vector<unsigned int>> solns;
EhOptimisedSolveUncancellable(n, k, eh_state, EhOptimisedSolveUncancellable(n, k, eh_state,
[](std::vector<unsigned char> soln) { return false; }); [](std::vector<unsigned char> soln) { return false; });
if (time) return timer_stop(tv_start);
return timer_stop();
else
return 0;
} }
double benchmark_solve_equihash_threaded(int nThreads) std::vector<double> benchmark_solve_equihash_threaded(int nThreads)
{ {
boost::thread_group solverThreads; std::vector<double> ret;
timer_start(); std::vector<std::future<double>> tasks;
for (int i = 0; i < nThreads; i++) std::vector<std::thread> threads;
solverThreads.create_thread(boost::bind(&benchmark_solve_equihash, false)); for (int i = 0; i < nThreads; i++) {
solverThreads.join_all(); std::packaged_task<double(void)> task(&benchmark_solve_equihash);
return timer_stop(); 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() double benchmark_verify_equihash()
@@ -143,9 +155,10 @@ double benchmark_verify_equihash()
CChainParams params = Params(CBaseChainParams::MAIN); CChainParams params = Params(CBaseChainParams::MAIN);
CBlock genesis = Params(CBaseChainParams::MAIN).GenesisBlock(); CBlock genesis = Params(CBaseChainParams::MAIN).GenesisBlock();
CBlockHeader genesis_header = genesis.GetBlockHeader(); CBlockHeader genesis_header = genesis.GetBlockHeader();
timer_start(); struct timeval tv_start;
timer_start(tv_start);
CheckEquihashSolution(&genesis_header, params); CheckEquihashSolution(&genesis_header, params);
return timer_stop(); return timer_stop(tv_start);
} }
double benchmark_large_tx() double benchmark_large_tx()
@@ -197,7 +210,8 @@ double benchmark_large_tx()
CTransaction final_spending_tx(spending_tx); CTransaction final_spending_tx(spending_tx);
// Benchmark signature verification costs: // Benchmark signature verification costs:
timer_start(); struct timeval tv_start;
timer_start(tv_start);
for (size_t i = 0; i < NUM_INPUTS; i++) { for (size_t i = 0; i < NUM_INPUTS; i++) {
ScriptError serror = SCRIPT_ERR_OK; ScriptError serror = SCRIPT_ERR_OK;
assert(VerifyScript(final_spending_tx.vin[i].scriptSig, assert(VerifyScript(final_spending_tx.vin[i].scriptSig,
@@ -206,6 +220,6 @@ double benchmark_large_tx()
TransactionSignatureChecker(&final_spending_tx, i), TransactionSignatureChecker(&final_spending_tx, i),
&serror)); &serror));
} }
return timer_stop(); return timer_stop(tv_start);
} }

View File

@@ -7,8 +7,8 @@
extern double benchmark_sleep(); extern double benchmark_sleep();
extern double benchmark_parameter_loading(); extern double benchmark_parameter_loading();
extern double benchmark_create_joinsplit(); extern double benchmark_create_joinsplit();
extern double benchmark_solve_equihash(bool time); extern double benchmark_solve_equihash();
extern double benchmark_solve_equihash_threaded(int nThreads); extern std::vector<double> benchmark_solve_equihash_threaded(int nThreads);
extern double benchmark_verify_joinsplit(const JSDescription &joinsplit); extern double benchmark_verify_joinsplit(const JSDescription &joinsplit);
extern double benchmark_verify_equihash(); extern double benchmark_verify_equihash();
extern double benchmark_large_tx(); extern double benchmark_large_tx();