mirror of
https://github.com/GOSTSec/sgminer
synced 2025-09-03 09:42:17 +00:00
Allow running cgminer in benchmark mode with a work file --benchfile
This commit is contained in:
parent
a825524325
commit
d3d1493bcf
27
README.md
27
README.md
@ -448,3 +448,30 @@ For example (this is wrapped, but it's all on one line for real):
|
|||||||
000000004a4366808f81d44f26df3d69d7dc4b3473385930462d9ab707b50498
|
000000004a4366808f81d44f26df3d69d7dc4b3473385930462d9ab707b50498
|
||||||
f681634a4f1f63d01a0cd43fb338000000000080000000000000000000000000
|
f681634a4f1f63d01a0cd43fb338000000000080000000000000000000000000
|
||||||
0000000000000000000000000000000000000000000000000000000080020000
|
0000000000000000000000000000000000000000000000000000000080020000
|
||||||
|
|
||||||
|
|
||||||
|
## Benchmark
|
||||||
|
|
||||||
|
The --benchmark option hashes a single fixed work item over and over and does
|
||||||
|
not submit shares to any pools.
|
||||||
|
|
||||||
|
The --benchfile <arg> option hashes the work given in the file <arg> supplied.
|
||||||
|
The format of the work file is:
|
||||||
|
version,merkleroot,prevhash,diffbits,noncetime
|
||||||
|
Any empty line or any line starting with '#' or '/' is ignored.
|
||||||
|
When it reaches the end of the file it continues back at the top.
|
||||||
|
|
||||||
|
The format of the data items matches the byte ordering and format of the
|
||||||
|
the bitcoind getblock RPC output.
|
||||||
|
|
||||||
|
An example file containing bitcoin block #1 would be:
|
||||||
|
|
||||||
|
# Block 1
|
||||||
|
1,0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098,00000000001
|
||||||
|
9d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f,1d00ffff,1231469665
|
||||||
|
|
||||||
|
However, the work data should be one line without the linebreak in the middle
|
||||||
|
|
||||||
|
If you use --benchfile <arg>, then --benchfile-display will output a log line,
|
||||||
|
for each nonce found, showing the nonce value in decimal and hex and the work
|
||||||
|
used to find it in hex.
|
||||||
|
204
sgminer.c
204
sgminer.c
@ -79,6 +79,29 @@ static char packagename[256];
|
|||||||
|
|
||||||
bool opt_work_update;
|
bool opt_work_update;
|
||||||
bool opt_protocol;
|
bool opt_protocol;
|
||||||
|
static struct benchfile_layout {
|
||||||
|
int length;
|
||||||
|
char *name;
|
||||||
|
} benchfile_data[] = {
|
||||||
|
{ 1, "Version" },
|
||||||
|
{ 64, "MerkleRoot" },
|
||||||
|
{ 64, "PrevHash" },
|
||||||
|
{ 8, "DifficultyBits" },
|
||||||
|
{ 10, "NonceTime" } // 10 digits
|
||||||
|
};
|
||||||
|
enum benchwork {
|
||||||
|
BENCHWORK_VERSION = 0,
|
||||||
|
BENCHWORK_MERKLEROOT,
|
||||||
|
BENCHWORK_PREVHASH,
|
||||||
|
BENCHWORK_DIFFBITS,
|
||||||
|
BENCHWORK_NONCETIME,
|
||||||
|
BENCHWORK_COUNT
|
||||||
|
};
|
||||||
|
static char *opt_benchfile;
|
||||||
|
static bool opt_benchfile_display;
|
||||||
|
static FILE *benchfile_in;
|
||||||
|
static int benchfile_line;
|
||||||
|
static int benchfile_work;
|
||||||
static bool opt_benchmark;
|
static bool opt_benchmark;
|
||||||
bool have_longpoll;
|
bool have_longpoll;
|
||||||
bool want_per_device_stats;
|
bool want_per_device_stats;
|
||||||
@ -1095,6 +1118,12 @@ static struct opt_table opt_config_table[] = {
|
|||||||
OPT_WITHOUT_ARG("--balance",
|
OPT_WITHOUT_ARG("--balance",
|
||||||
set_balance, &pool_strategy,
|
set_balance, &pool_strategy,
|
||||||
"Change multipool strategy from failover to even share balance"),
|
"Change multipool strategy from failover to even share balance"),
|
||||||
|
OPT_WITH_ARG("--benchfile",
|
||||||
|
opt_set_charp, opt_show_charp, &opt_benchfile,
|
||||||
|
"Run cgminer in benchmark mode using a work file - produces no shares"),
|
||||||
|
OPT_WITHOUT_ARG("--benchfile-display",
|
||||||
|
opt_set_bool, &opt_benchfile_display,
|
||||||
|
"Display each benchfile nonce found"),
|
||||||
OPT_WITHOUT_ARG("--benchmark",
|
OPT_WITHOUT_ARG("--benchmark",
|
||||||
opt_set_bool, &opt_benchmark,
|
opt_set_bool, &opt_benchmark,
|
||||||
"Run sgminer in benchmark mode - produces no shares"),
|
"Run sgminer in benchmark mode - produces no shares"),
|
||||||
@ -2989,6 +3018,154 @@ static void get_benchmark_work(struct work *work)
|
|||||||
calc_diff(work, 0);
|
calc_diff(work, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void benchfile_dspwork(struct work *work, uint32_t nonce)
|
||||||
|
{
|
||||||
|
char buf[1024];
|
||||||
|
uint32_t dn;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
dn = 0;
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
dn *= 0x100;
|
||||||
|
dn += nonce & 0xff;
|
||||||
|
nonce /= 0x100;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((sizeof(work->data) * 2 + 1) > sizeof(buf))
|
||||||
|
quithere(1, "BENCHFILE Invalid buf size");
|
||||||
|
|
||||||
|
__bin2hex(buf, work->data, sizeof(work->data));
|
||||||
|
|
||||||
|
applog(LOG_ERR, "BENCHFILE nonce %u=0x%08x for work=%s",
|
||||||
|
(unsigned int)dn, (unsigned int)dn, buf);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool benchfile_get_work(struct work *work)
|
||||||
|
{
|
||||||
|
char buf[1024];
|
||||||
|
char item[1024];
|
||||||
|
bool got = false;
|
||||||
|
|
||||||
|
if (!benchfile_in) {
|
||||||
|
if (opt_benchfile)
|
||||||
|
benchfile_in = fopen(opt_benchfile, "r");
|
||||||
|
else
|
||||||
|
quit(1, "BENCHFILE Invalid benchfile NULL");
|
||||||
|
|
||||||
|
if (!benchfile_in)
|
||||||
|
quit(1, "BENCHFILE Failed to open benchfile '%s'", opt_benchfile);
|
||||||
|
|
||||||
|
benchfile_line = 0;
|
||||||
|
|
||||||
|
if (!fgets(buf, 1024, benchfile_in))
|
||||||
|
quit(1, "BENCHFILE Failed to read benchfile '%s'", opt_benchfile);
|
||||||
|
|
||||||
|
got = true;
|
||||||
|
benchfile_work = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!got) {
|
||||||
|
if (!fgets(buf, 1024, benchfile_in)) {
|
||||||
|
if (benchfile_work == 0)
|
||||||
|
quit(1, "BENCHFILE No work in benchfile '%s'", opt_benchfile);
|
||||||
|
fclose(benchfile_in);
|
||||||
|
benchfile_in = NULL;
|
||||||
|
return benchfile_get_work(work);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
benchfile_line++;
|
||||||
|
|
||||||
|
// Empty lines and lines starting with '#' or '/' are ignored
|
||||||
|
if (*buf != '\0' && *buf != '#' && *buf != '/') {
|
||||||
|
char *commas[BENCHWORK_COUNT];
|
||||||
|
int i, j, len;
|
||||||
|
|
||||||
|
commas[0] = buf;
|
||||||
|
for (i = 1; i < BENCHWORK_COUNT; i++) {
|
||||||
|
commas[i] = strchr(commas[i-1], ',');
|
||||||
|
if (!commas[i]) {
|
||||||
|
quit(1, "BENCHFILE Invalid input file line %d"
|
||||||
|
" - field count is %d but should be %d",
|
||||||
|
benchfile_line, i, BENCHWORK_COUNT);
|
||||||
|
}
|
||||||
|
len = commas[i] - commas[i-1];
|
||||||
|
if (benchfile_data[i-1].length &&
|
||||||
|
(len != benchfile_data[i-1].length)) {
|
||||||
|
quit(1, "BENCHFILE Invalid input file line %d "
|
||||||
|
"field %d (%s) length is %d but should be %d",
|
||||||
|
benchfile_line, i,
|
||||||
|
benchfile_data[i-1].name,
|
||||||
|
len, benchfile_data[i-1].length);
|
||||||
|
}
|
||||||
|
|
||||||
|
*(commas[i]++) = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
// NonceTime may have LF's etc
|
||||||
|
len = strlen(commas[BENCHWORK_NONCETIME]);
|
||||||
|
if (len < benchfile_data[BENCHWORK_NONCETIME].length) {
|
||||||
|
quit(1, "BENCHFILE Invalid input file line %d field %d"
|
||||||
|
" (%s) length is %d but should be least %d",
|
||||||
|
benchfile_line, BENCHWORK_NONCETIME+1,
|
||||||
|
benchfile_data[BENCHWORK_NONCETIME].name, len,
|
||||||
|
benchfile_data[BENCHWORK_NONCETIME].length);
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(item, "0000000%c", commas[BENCHWORK_VERSION][0]);
|
||||||
|
|
||||||
|
j = strlen(item);
|
||||||
|
for (i = benchfile_data[BENCHWORK_PREVHASH].length-8; i >= 0; i -= 8) {
|
||||||
|
sprintf(&(item[j]), "%.8s", &commas[BENCHWORK_PREVHASH][i]);
|
||||||
|
j += 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = benchfile_data[BENCHWORK_MERKLEROOT].length-8; i >= 0; i -= 8) {
|
||||||
|
sprintf(&(item[j]), "%.8s", &commas[BENCHWORK_MERKLEROOT][i]);
|
||||||
|
j += 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
long time = atol(commas[BENCHWORK_NONCETIME]);
|
||||||
|
|
||||||
|
sprintf(&(item[j]), "%08lx", time);
|
||||||
|
j += 8;
|
||||||
|
|
||||||
|
strcpy(&(item[j]), commas[BENCHWORK_DIFFBITS]);
|
||||||
|
j += benchfile_data[BENCHWORK_DIFFBITS].length;
|
||||||
|
|
||||||
|
memset(work, 0, sizeof(*work));
|
||||||
|
|
||||||
|
hex2bin(work->data, item, j >> 1);
|
||||||
|
|
||||||
|
calc_midstate(work);
|
||||||
|
|
||||||
|
benchfile_work++;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} while (fgets(buf, 1024, benchfile_in));
|
||||||
|
|
||||||
|
if (benchfile_work == 0)
|
||||||
|
quit(1, "BENCHFILE No work in benchfile '%s'", opt_benchfile);
|
||||||
|
fclose(benchfile_in);
|
||||||
|
benchfile_in = NULL;
|
||||||
|
return benchfile_get_work(work);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void get_benchfile_work(struct work *work)
|
||||||
|
{
|
||||||
|
benchfile_get_work(work);
|
||||||
|
work->mandatory = true;
|
||||||
|
work->pool = pools[0];
|
||||||
|
cgtime(&work->tv_getwork);
|
||||||
|
copy_time(&work->tv_getwork_reply, &work->tv_getwork);
|
||||||
|
work->getwork_mode = GETWORK_MODE_BENCHMARK;
|
||||||
|
calc_diff(work, 0);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef HAVE_CURSES
|
#ifdef HAVE_CURSES
|
||||||
static void disable_curses_windows(void)
|
static void disable_curses_windows(void)
|
||||||
{
|
{
|
||||||
@ -3494,7 +3671,7 @@ static bool stale_work(struct work *work, bool share)
|
|||||||
struct pool *pool;
|
struct pool *pool;
|
||||||
int getwork_delay;
|
int getwork_delay;
|
||||||
|
|
||||||
if (opt_benchmark)
|
if (opt_benchmark || opt_benchfile)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (work->work_block != work_block) {
|
if (work->work_block != work_block) {
|
||||||
@ -6091,6 +6268,9 @@ bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (opt_benchfile && opt_benchfile_display)
|
||||||
|
benchfile_dspwork(work, nonce);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6111,6 +6291,10 @@ bool submit_noffset_nonce(struct thr_info *thr, struct work *work_in, uint32_t n
|
|||||||
}
|
}
|
||||||
ret = true;
|
ret = true;
|
||||||
update_work_stats(thr, work);
|
update_work_stats(thr, work);
|
||||||
|
|
||||||
|
if (opt_benchfile && opt_benchfile_display)
|
||||||
|
benchfile_dspwork(work, nonce);
|
||||||
|
|
||||||
if (!fulltest(work->hash, work->target)) {
|
if (!fulltest(work->hash, work->target)) {
|
||||||
applog(LOG_INFO, "%s %d: Share above target", thr->cgpu->drv->name,
|
applog(LOG_INFO, "%s %d: Share above target", thr->cgpu->drv->name,
|
||||||
thr->cgpu->device_id);
|
thr->cgpu->device_id);
|
||||||
@ -6932,7 +7116,7 @@ static void *watchpool_thread(void __maybe_unused *userdata)
|
|||||||
for (i = 0; i < total_pools; i++) {
|
for (i = 0; i < total_pools; i++) {
|
||||||
struct pool *pool = pools[i];
|
struct pool *pool = pools[i];
|
||||||
|
|
||||||
if (!opt_benchmark)
|
if (!opt_benchmark && !opt_benchfile)
|
||||||
reap_curl(pool);
|
reap_curl(pool);
|
||||||
|
|
||||||
/* Get a rolling utility per pool over 10 mins */
|
/* Get a rolling utility per pool over 10 mins */
|
||||||
@ -7833,14 +8017,17 @@ int main(int argc, char *argv[])
|
|||||||
if (!config_loaded)
|
if (!config_loaded)
|
||||||
load_default_config();
|
load_default_config();
|
||||||
|
|
||||||
if (opt_benchmark) {
|
if (opt_benchmark || opt_benchfile) {
|
||||||
struct pool *pool;
|
struct pool *pool;
|
||||||
|
|
||||||
// FIXME: executes always (leftover from SHA256d days)
|
// FIXME: executes always (leftover from SHA256d days)
|
||||||
quit(1, "Cannot use benchmark mode with scrypt");
|
quit(1, "Cannot use benchmark mode with scrypt");
|
||||||
pool = add_pool();
|
pool = add_pool();
|
||||||
pool->rpc_url = malloc(255);
|
pool->rpc_url = malloc(255);
|
||||||
strcpy(pool->rpc_url, "Benchmark");
|
if (opt_benchfile)
|
||||||
|
strcpy(pool->rpc_url, "Benchfile");
|
||||||
|
else
|
||||||
|
strcpy(pool->rpc_url, "Benchmark");
|
||||||
pool->rpc_user = pool->rpc_url;
|
pool->rpc_user = pool->rpc_url;
|
||||||
pool->rpc_pass = pool->rpc_url;
|
pool->rpc_pass = pool->rpc_url;
|
||||||
enable_pool(pool);
|
enable_pool(pool);
|
||||||
@ -8025,7 +8212,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt_benchmark)
|
if (opt_benchmark || opt_benchfile)
|
||||||
goto begin_bench;
|
goto begin_bench;
|
||||||
|
|
||||||
/* Set pool state */
|
/* Set pool state */
|
||||||
@ -8218,7 +8405,12 @@ retry:
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt_benchmark) {
|
if (opt_benchfile) {
|
||||||
|
get_benchfile_work(work);
|
||||||
|
applog(LOG_DEBUG, "Generated benchfile work");
|
||||||
|
stage_work(work);
|
||||||
|
continue;
|
||||||
|
} else if (opt_benchmark) {
|
||||||
get_benchmark_work(work);
|
get_benchmark_work(work);
|
||||||
applog(LOG_DEBUG, "Generated benchmark work");
|
applog(LOG_DEBUG, "Generated benchmark work");
|
||||||
stage_work(work);
|
stage_work(work);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user