This commit is contained in:
Jay D Dee
2021-02-12 15:16:53 -05:00
parent 06bfaa1249
commit dc6b007a18
10 changed files with 111 additions and 97 deletions

View File

@@ -59,7 +59,7 @@ Notes about included DLL files:
Downloading DLL files from alternative sources presents an inherent Downloading DLL files from alternative sources presents an inherent
security risk if their source is unknown. All DLL files included have security risk if their source is unknown. All DLL files included have
been copied from the Ubuntu-20.04 instalation or compiled by me from been copied from the Ubuntu-20.04 installation or compiled by me from
source code obtained from the author's official repository. The exact source code obtained from the author's official repository. The exact
procedure is documented in the build instructions for Windows: procedure is documented in the build instructions for Windows:
https://github.com/JayDDee/cpuminer-opt/wiki/Compiling-from-source https://github.com/JayDDee/cpuminer-opt/wiki/Compiling-from-source

View File

@@ -65,6 +65,14 @@ If not what makes it happen or not happen?
Change Log Change Log
---------- ----------
v3.15.6
Implement keccak pre-hash optimization for x16* algos.
Move conditional mining test to before get_new_work in miner thread.
Add test for share reject reason when solo mining.
Add support for floating point, as well as integer, "networkhasps" in
RPC getmininginfo method.
v3.15.5 v3.15.5
Fix stratum jobs lost if 2 jobs received in less than one second. Fix stratum jobs lost if 2 jobs received in less than one second.

View File

@@ -419,7 +419,6 @@ void exec_hash_function( int algo, void *output, const void *pdata )
const char* const algo_alias_map[][2] = const char* const algo_alias_map[][2] =
{ {
// alias proper // alias proper
{ "argon2d-crds", "argon2d250" },
{ "argon2d-dyn", "argon2d500" }, { "argon2d-dyn", "argon2d500" },
{ "argon2d-uis", "argon2d4096" }, { "argon2d-uis", "argon2d4096" },
{ "bcd", "x13bcd" }, { "bcd", "x13bcd" },

View File

@@ -201,6 +201,7 @@
#define IOTA(r) XOR64_IOTA(a00, a00, r) #define IOTA(r) XOR64_IOTA(a00, a00, r)
#ifdef P0 #ifdef P0
#undef P0
#undef P1 #undef P1
#undef P2 #undef P2
#undef P3 #undef P3

View File

@@ -16,8 +16,7 @@
#if defined (X16R_8WAY) #if defined (X16R_8WAY)
// Perform midstate prehash of hash functions with block size <= 64 bytes // Perform midstate prehash of hash functions with block size <= 72 bytes.
// and interleave 4x64 before nonce insertion for final hash.
void x16r_8way_prehash( void *vdata, void *pdata ) void x16r_8way_prehash( void *vdata, void *pdata )
{ {
@@ -34,6 +33,11 @@ void x16r_8way_prehash( void *vdata, void *pdata )
jh512_8way_init( &x16r_ctx.jh ); jh512_8way_init( &x16r_ctx.jh );
jh512_8way_update( &x16r_ctx.jh, vdata, 64 ); jh512_8way_update( &x16r_ctx.jh, vdata, 64 );
break; break;
case KECCAK:
mm512_bswap32_intrlv80_8x64( vdata, pdata );
keccak512_8way_init( &x16r_ctx.keccak );
keccak512_8way_update( &x16r_ctx.keccak, vdata, 72 );
break;
case SKEIN: case SKEIN:
mm512_bswap32_intrlv80_8x64( vdata, pdata ); mm512_bswap32_intrlv80_8x64( vdata, pdata );
skein512_8way_init( &x16r_ctx.skein ); skein512_8way_init( &x16r_ctx.skein );
@@ -173,13 +177,13 @@ int x16r_8way_hash_generic( void* output, const void* input, int thrid )
hash7, vhash ); hash7, vhash );
break; break;
case KECCAK: case KECCAK:
keccak512_8way_init( &ctx.keccak ); if ( i == 0 )
if ( i == 0 ) keccak512_8way_update( &ctx.keccak, input + (72<<3), 8 );
keccak512_8way_update( &ctx.keccak, input, size );
else else
{ {
intrlv_8x64( vhash, in0, in1, in2, in3, in4, in5, in6, in7, intrlv_8x64( vhash, in0, in1, in2, in3, in4, in5, in6, in7,
size<<3 ); size<<3 );
keccak512_8way_init( &ctx.keccak );
keccak512_8way_update( &ctx.keccak, vhash, size ); keccak512_8way_update( &ctx.keccak, vhash, size );
} }
keccak512_8way_close( &ctx.keccak, vhash ); keccak512_8way_close( &ctx.keccak, vhash );
@@ -490,6 +494,7 @@ int scanhash_x16r_8way( struct work *work, uint32_t max_nonce,
{ {
x16_r_s_getAlgoString( (const uint8_t*)bedata1, x16r_hash_order ); x16_r_s_getAlgoString( (const uint8_t*)bedata1, x16r_hash_order );
s_ntime = ntime; s_ntime = ntime;
if ( opt_debug && !thr_id ) if ( opt_debug && !thr_id )
applog( LOG_INFO, "hash order %s (%08x)", x16r_hash_order, ntime ); applog( LOG_INFO, "hash order %s (%08x)", x16r_hash_order, ntime );
} }
@@ -533,6 +538,11 @@ void x16r_4way_prehash( void *vdata, void *pdata )
jh512_4way_init( &x16r_ctx.jh ); jh512_4way_init( &x16r_ctx.jh );
jh512_4way_update( &x16r_ctx.jh, vdata, 64 ); jh512_4way_update( &x16r_ctx.jh, vdata, 64 );
break; break;
case KECCAK:
mm256_bswap32_intrlv80_4x64( vdata, pdata );
keccak512_4way_init( &x16r_ctx.keccak );
keccak512_4way_update( &x16r_ctx.keccak, vdata, 72 );
break;
case SKEIN: case SKEIN:
mm256_bswap32_intrlv80_4x64( vdata, pdata ); mm256_bswap32_intrlv80_4x64( vdata, pdata );
skein512_4way_prehash64( &x16r_ctx.skein, vdata ); skein512_4way_prehash64( &x16r_ctx.skein, vdata );
@@ -646,12 +656,12 @@ int x16r_4way_hash_generic( void* output, const void* input, int thrid )
dintrlv_4x64_512( hash0, hash1, hash2, hash3, vhash ); dintrlv_4x64_512( hash0, hash1, hash2, hash3, vhash );
break; break;
case KECCAK: case KECCAK:
keccak512_4way_init( &ctx.keccak ); if ( i == 0 )
if ( i == 0 ) keccak512_4way_update( &ctx.keccak, input + (72<<2), 8 );
keccak512_4way_update( &ctx.keccak, input, size );
else else
{ {
intrlv_4x64( vhash, in0, in1, in2, in3, size<<3 ); intrlv_4x64( vhash, in0, in1, in2, in3, size<<3 );
keccak512_4way_init( &ctx.keccak );
keccak512_4way_update( &ctx.keccak, vhash, size ); keccak512_4way_update( &ctx.keccak, vhash, size );
} }
keccak512_4way_close( &ctx.keccak, vhash ); keccak512_4way_close( &ctx.keccak, vhash );
@@ -883,7 +893,7 @@ int scanhash_x16r_4way( struct work *work, uint32_t max_nonce,
x16_r_s_getAlgoString( (const uint8_t*)bedata1, x16r_hash_order ); x16_r_s_getAlgoString( (const uint8_t*)bedata1, x16r_hash_order );
s_ntime = ntime; s_ntime = ntime;
if ( opt_debug && !thr_id ) if ( opt_debug && !thr_id )
applog( LOG_INFO, "hash order %s (%08x)", x16r_hash_order, ntime ); applog( LOG_INFO, "hash order %s (%08x)", x16r_hash_order, ntime );
} }
x16r_4way_prehash( vdata, pdata ); x16r_4way_prehash( vdata, pdata );

20
configure vendored
View File

@@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for cpuminer-opt 3.15.5. # Generated by GNU Autoconf 2.69 for cpuminer-opt 3.15.6.
# #
# #
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -577,8 +577,8 @@ MAKEFLAGS=
# Identity of this package. # Identity of this package.
PACKAGE_NAME='cpuminer-opt' PACKAGE_NAME='cpuminer-opt'
PACKAGE_TARNAME='cpuminer-opt' PACKAGE_TARNAME='cpuminer-opt'
PACKAGE_VERSION='3.15.5' PACKAGE_VERSION='3.15.6'
PACKAGE_STRING='cpuminer-opt 3.15.5' PACKAGE_STRING='cpuminer-opt 3.15.6'
PACKAGE_BUGREPORT='' PACKAGE_BUGREPORT=''
PACKAGE_URL='' PACKAGE_URL=''
@@ -1332,7 +1332,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing. # Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh. # This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF cat <<_ACEOF
\`configure' configures cpuminer-opt 3.15.5 to adapt to many kinds of systems. \`configure' configures cpuminer-opt 3.15.6 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]... Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1404,7 +1404,7 @@ fi
if test -n "$ac_init_help"; then if test -n "$ac_init_help"; then
case $ac_init_help in case $ac_init_help in
short | recursive ) echo "Configuration of cpuminer-opt 3.15.5:";; short | recursive ) echo "Configuration of cpuminer-opt 3.15.6:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
@@ -1509,7 +1509,7 @@ fi
test -n "$ac_init_help" && exit $ac_status test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then if $ac_init_version; then
cat <<\_ACEOF cat <<\_ACEOF
cpuminer-opt configure 3.15.5 cpuminer-opt configure 3.15.6
generated by GNU Autoconf 2.69 generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc. Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2012,7 +2012,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake. running configure, to aid debugging if configure makes a mistake.
It was created by cpuminer-opt $as_me 3.15.5, which was It was created by cpuminer-opt $as_me 3.15.6, which was
generated by GNU Autoconf 2.69. Invocation command line was generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@ $ $0 $@
@@ -2993,7 +2993,7 @@ fi
# Define the identity of the package. # Define the identity of the package.
PACKAGE='cpuminer-opt' PACKAGE='cpuminer-opt'
VERSION='3.15.5' VERSION='3.15.6'
cat >>confdefs.h <<_ACEOF cat >>confdefs.h <<_ACEOF
@@ -6690,7 +6690,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their # report actual input values of CONFIG_FILES etc. instead of their
# values after options handling. # values after options handling.
ac_log=" ac_log="
This file was extended by cpuminer-opt $as_me 3.15.5, which was This file was extended by cpuminer-opt $as_me 3.15.6, which was
generated by GNU Autoconf 2.69. Invocation command line was generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES CONFIG_FILES = $CONFIG_FILES
@@ -6756,7 +6756,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\ ac_cs_version="\\
cpuminer-opt config.status 3.15.5 cpuminer-opt config.status 3.15.6
configured by $0, generated by GNU Autoconf 2.69, configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\" with options \\"\$ac_cs_config\\"

View File

@@ -1,4 +1,4 @@
AC_INIT([cpuminer-opt], [3.15.5]) AC_INIT([cpuminer-opt], [3.15.6])
AC_PREREQ([2.59c]) AC_PREREQ([2.59c])
AC_CANONICAL_SYSTEM AC_CANONICAL_SYSTEM

View File

@@ -490,8 +490,13 @@ static bool get_mininginfo( CURL *curl, struct work *work )
} }
key = json_object_get( res, "networkhashps" ); key = json_object_get( res, "networkhashps" );
if ( key && json_is_integer( key ) ) if ( key )
net_hashrate = (double) json_integer_value( key ); {
if ( json_is_integer( key ) )
net_hashrate = (double) json_integer_value( key );
else if ( json_is_real( key ) )
net_hashrate = (double) json_real_value( key );
}
key = json_object_get( res, "blocks" ); key = json_object_get( res, "blocks" );
if ( key && json_is_integer( key ) ) if ( key && json_is_integer( key ) )
@@ -506,26 +511,7 @@ static bool get_mininginfo( CURL *curl, struct work *work )
// complete missing data from getwork // complete missing data from getwork
work->height = (uint32_t) net_blocks + 1; work->height = (uint32_t) net_blocks + 1;
if ( work->height > g_work.height ) if ( work->height > g_work.height )
{
restart_threads(); restart_threads();
/* redundant with new block log
if ( !opt_quiet )
{
char netinfo[64] = { 0 };
char srate[32] = { 0 };
sprintf( netinfo, "diff %.2f", net_diff );
if ( net_hashrate )
{
format_hashrate( net_hashrate, srate );
strcat( netinfo, ", net " );
strcat( netinfo, srate );
}
applog( LOG_BLUE, "%s block %d, %s",
algo_names[opt_algo], work->height, netinfo );
}
*/
}
} // res } // res
} }
json_decref( val ); json_decref( val );
@@ -920,12 +906,12 @@ static bool gbt_work_decode( const json_t *val, struct work *work )
tmp = json_object_get( val, "workid" ); tmp = json_object_get( val, "workid" );
if ( tmp ) if ( tmp )
{ {
if ( !json_is_string( tmp ) ) if ( !json_is_string( tmp ) )
{ {
applog( LOG_ERR, "JSON invalid workid" ); applog( LOG_ERR, "JSON invalid workid" );
goto out; goto out;
} }
work->workid = strdup( json_string_value( tmp ) ); work->workid = strdup( json_string_value( tmp ) );
} }
rc = true; rc = true;
@@ -1078,13 +1064,12 @@ void report_summary_log( bool force )
if ( accepted_share_count < submitted_share_count ) if ( accepted_share_count < submitted_share_count )
{ {
double ltd = exp32 * last_targetdiff;
double lost_ghrate = uptime.tv_sec == 0 ? 0. double lost_ghrate = uptime.tv_sec == 0 ? 0.
: exp32 * last_targetdiff : ltd * (double)(submitted_share_count - accepted_share_count )
* (double)(submitted_share_count - accepted_share_count ) / (double)uptime.tv_sec;
/ (double)uptime.tv_sec;
double lost_shrate = share_time == 0. ? 0. double lost_shrate = share_time == 0. ? 0.
: exp32 * last_targetdiff * (double)(submits - accepts ) : ltd * (double)(submits - accepts ) / share_time;
/ share_time;
char lshr_units[4] = {0}; char lshr_units[4] = {0};
char lghr_units[4] = {0}; char lghr_units[4] = {0};
scale_hash_for_display( &lost_shrate, lshr_units ); scale_hash_for_display( &lost_shrate, lshr_units );
@@ -1190,9 +1175,11 @@ static int share_result( int result, struct work *work,
{ {
sprintf( ares, "A%d", accepted_share_count ); sprintf( ares, "A%d", accepted_share_count );
sprintf( bres, "B%d", solved_block_count ); sprintf( bres, "B%d", solved_block_count );
stale = work ? work->data[ algo_gate.ntime_index ] if ( reason )
!= g_work.data[ algo_gate.ntime_index ] : false; stale = strstr( reason, "job" );
if ( reason ) stale = stale || strstr( reason, "job" ); else if ( work )
stale = work->data[ algo_gate.ntime_index ]
!= g_work.data[ algo_gate.ntime_index ];
if ( stale ) if ( stale )
{ {
stale_share_count++; stale_share_count++;
@@ -1260,14 +1247,13 @@ static int share_result( int result, struct work *work,
if ( unlikely( !( opt_quiet || result || stale ) ) ) if ( unlikely( !( opt_quiet || result || stale ) ) )
{ {
uint32_t str[8]; uint32_t str[8];
uint32_t *targ;
if ( reason ) if ( reason ) applog( LOG_WARNING, "Reject reason: %s", reason );
applog( LOG_WARNING, "Reject reason: %s", reason );
// display share hash and target for troubleshooting
diff_to_hash( str, my_stats.share_diff ); diff_to_hash( str, my_stats.share_diff );
applog2( LOG_INFO, "Hash: %08x%08x%08x...", str[7], str[6], str[5] ); applog2( LOG_INFO, "Hash: %08x%08x%08x...", str[7], str[6], str[5] );
uint32_t *targ;
if ( work ) if ( work )
targ = work->target; targ = work->target;
else else
@@ -1580,6 +1566,7 @@ start:
{ {
double miner_hr = 0.; double miner_hr = 0.;
double net_hr = net_hashrate; double net_hr = net_hashrate;
double nd = net_diff * exp32;
char net_hr_units[4] = {0}; char net_hr_units[4] = {0};
char miner_hr_units[4] = {0}; char miner_hr_units[4] = {0};
char net_ttf[32]; char net_ttf[32];
@@ -1594,11 +1581,11 @@ start:
pthread_mutex_unlock( &stats_lock ); pthread_mutex_unlock( &stats_lock );
if ( net_hr > 0. ) if ( net_hr > 0. )
sprintf_et( net_ttf, ( net_diff * exp32 ) / net_hr ); sprintf_et( net_ttf, nd / net_hr );
else else
sprintf( net_ttf, "NA" ); sprintf( net_ttf, "NA" );
if ( miner_hr > 0. ) if ( miner_hr > 0. )
sprintf_et( miner_ttf, ( net_diff * exp32 ) / miner_hr ); sprintf_et( miner_ttf, nd / miner_hr );
else else
sprintf( miner_ttf, "NA" ); sprintf( miner_ttf, "NA" );
@@ -1848,10 +1835,19 @@ bool submit_solution( struct work *work, const void *hash,
work->data[ algo_gate.ntime_index ] ); work->data[ algo_gate.ntime_index ] );
} }
if ( unlikely( lowdiff_debug ) ) if ( opt_debug )
{ {
uint32_t* h = (uint32_t*)hash; uint32_t* h = (uint32_t*)hash;
uint32_t* t = (uint32_t*)work->target; uint32_t* t = (uint32_t*)work->target;
uint32_t* d = (uint32_t*)work->data;
unsigned char *xnonce2str = abin2hex( work->xnonce2,
work->xnonce2_len );
applog(LOG_INFO,"Thread %d, Nonce %08x, Xnonce2 %s", thr->id,
work->data[ algo_gate.nonce_index ], xnonce2str );
free( xnonce2str );
applog(LOG_INFO,"Data[0:19]: %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x", d[0],d[1],d[2],d[3],d[4],d[5],d[6],d[7],d[8],d[9] );
applog(LOG_INFO," : %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x", d[10],d[11],d[12],d[13],d[14],d[15],d[16],d[17],d[18],d[19]);
applog(LOG_INFO,"Hash[7:0]: %08x %08x %08x %08x %08x %08x %08x %08x", applog(LOG_INFO,"Hash[7:0]: %08x %08x %08x %08x %08x %08x %08x %08x",
h[7],h[6],h[5],h[4],h[3],h[2],h[1],h[0]); h[7],h[6],h[5],h[4],h[3],h[2],h[1],h[0]);
applog(LOG_INFO,"Targ[7:0]: %08x %08x %08x %08x %08x %08x %08x %08x", applog(LOG_INFO,"Targ[7:0]: %08x %08x %08x %08x %08x %08x %08x %08x",
@@ -2066,11 +2062,12 @@ static void stratum_gen_work( struct stratum_ctx *sctx, struct work *g_work )
if ( likely( hr > 0. ) ) if ( likely( hr > 0. ) )
{ {
double nd = net_diff * exp32;
char hr_units[4] = {0}; char hr_units[4] = {0};
char block_ttf[32]; char block_ttf[32];
char share_ttf[32]; char share_ttf[32];
sprintf_et( block_ttf, ( net_diff * exp32 ) / hr ); sprintf_et( block_ttf, nd / hr );
sprintf_et( share_ttf, ( g_work->targetdiff * exp32 ) / hr ); sprintf_et( share_ttf, ( g_work->targetdiff * exp32 ) / hr );
scale_hash_for_display ( &hr, hr_units ); scale_hash_for_display ( &hr, hr_units );
applog2( LOG_INFO, "TTF @ %.2f %sh/s: Block %s, Share %s", applog2( LOG_INFO, "TTF @ %.2f %sh/s: Block %s, Share %s",
@@ -2086,7 +2083,7 @@ static void stratum_gen_work( struct stratum_ctx *sctx, struct work *g_work )
: et.tv_sec / ( last_block_height - session_first_block ); : et.tv_sec / ( last_block_height - session_first_block );
if ( net_diff && net_ttf ) if ( net_diff && net_ttf )
{ {
double net_hr = net_diff * exp32 / net_ttf; double net_hr = nd / net_ttf;
char net_hr_units[4] = {0}; char net_hr_units[4] = {0};
scale_hash_for_display ( &net_hr, net_hr_units ); scale_hash_for_display ( &net_hr, net_hr_units );
@@ -2253,12 +2250,6 @@ static void *miner_thread( void *userdata )
if ( unlikely( !algo_gate.ready_to_mine( &work, &stratum, thr_id ) ) ) if ( unlikely( !algo_gate.ready_to_mine( &work, &stratum, thr_id ) ) )
continue; continue;
// conditional mining
if ( unlikely( !wanna_mine( thr_id ) ) )
{
sleep(5);
continue;
}
// LP_SCANTIME overrides opt_scantime option, is this right? // LP_SCANTIME overrides opt_scantime option, is this right?
@@ -2445,6 +2436,14 @@ static void *miner_thread( void *userdata )
#endif #endif
} }
} // benchmark } // benchmark
// conditional mining
if ( unlikely( !wanna_mine( thr_id ) ) )
{
sleep(5);
continue;
}
} // miner_thread loop } // miner_thread loop
out: out:

11
miner.h
View File

@@ -643,7 +643,7 @@ static const char* const algo_names[] = {
"lyra2z330", "lyra2z330",
"m7m", "m7m",
"minotaur", "minotaur",
"myr-gr", "myr-gr",
"neoscrypt", "neoscrypt",
"nist5", "nist5",
"pentablake", "pentablake",
@@ -771,7 +771,7 @@ Options:\n\
allium Garlicoin (GRLC)\n\ allium Garlicoin (GRLC)\n\
anime Animecoin (ANI)\n\ anime Animecoin (ANI)\n\
argon2 Argon2 Coin (AR2)\n\ argon2 Argon2 Coin (AR2)\n\
argon2d250 argon2d-crds, Credits (CRDS)\n\ argon2d250\n\
argon2d500 argon2d-dyn, Dynamic (DYN)\n\ argon2d500 argon2d-dyn, Dynamic (DYN)\n\
argon2d4096 argon2d-uis, Unitus (UIS)\n\ argon2d4096 argon2d-uis, Unitus (UIS)\n\
axiom Shabal-256 MemoHash\n\ axiom Shabal-256 MemoHash\n\
@@ -796,13 +796,13 @@ Options:\n\
lyra2h Hppcoin\n\ lyra2h Hppcoin\n\
lyra2re lyra2\n\ lyra2re lyra2\n\
lyra2rev2 lyrav2\n\ lyra2rev2 lyrav2\n\
lyra2rev3 lyrav2v3, Vertcoin\n\ lyra2rev3 lyrav2v3\n\
lyra2z\n\ lyra2z\n\
lyra2z330 Lyra2 330 rows\n\ lyra2z330 Lyra2 330 rows\n\
m7m Magi (XMG)\n\ m7m Magi (XMG)\n\
myr-gr Myriad-Groestl\n\ myr-gr Myriad-Groestl\n\
minotaur Ringcoin (RNG)\n\ minotaur Ringcoin (RNG)\n\
neoscrypt NeoScrypt(128, 2, 1)\n\ neoscrypt NeoScrypt(128, 2, 1)\n\
nist5 Nist5\n\ nist5 Nist5\n\
pentablake 5 x blake512\n\ pentablake 5 x blake512\n\
phi1612 phi\n\ phi1612 phi\n\
@@ -816,7 +816,7 @@ Options:\n\
sha256d Double SHA-256\n\ sha256d Double SHA-256\n\
sha256q Quad SHA-256, Pyrite (PYE)\n\ sha256q Quad SHA-256, Pyrite (PYE)\n\
sha256t Triple SHA-256, Onecoin (OC)\n\ sha256t Triple SHA-256, Onecoin (OC)\n\
sha3d Double Keccak256 (BSHA3)\n\ sha3d Double Keccak256 (BSHA3)\n\
shavite3 Shavite3\n\ shavite3 Shavite3\n\
skein Skein+Sha (Skeincoin)\n\ skein Skein+Sha (Skeincoin)\n\
skein2 Double Skein (Woodcoin)\n\ skein2 Double Skein (Woodcoin)\n\
@@ -875,7 +875,6 @@ Options:\n\
-s, --scantime=N upper bound on time spent scanning current work when\n\ -s, --scantime=N upper bound on time spent scanning current work when\n\
long polling is unavailable, in seconds (default: 5)\n\ long polling is unavailable, in seconds (default: 5)\n\
--randomize Randomize scan range start to reduce duplicates\n\ --randomize Randomize scan range start to reduce duplicates\n\
--reset-on-stale Workaround reset stratum if too many stale shares\n\
-f, --diff-factor Divide req. difficulty by this factor (std is 1.0)\n\ -f, --diff-factor Divide req. difficulty by this factor (std is 1.0)\n\
-m, --diff-multiplier Multiply difficulty by this factor (std is 1.0)\n\ -m, --diff-multiplier Multiply difficulty by this factor (std is 1.0)\n\
--hash-meter Display thread hash rates\n\ --hash-meter Display thread hash rates\n\

36
util.c
View File

@@ -1048,53 +1048,51 @@ bool fulltest( const uint32_t *hash, const uint32_t *target )
return rc; return rc;
} }
// Mathmatically the difficulty is simply the reciprocal of the hash. // Mathmatically the difficulty is simply the reciprocal of the hash: d = 1/h.
// Both are real numbers but the hash (target) is represented as a 256 bit // Both are real numbers but the hash (target) is represented as a 256 bit
// number with the upper 32 bits representing the whole integer part and the // fixed point number with the upper 32 bits representing the whole integer
// lower 224 bits representing the fractional part: // part and the lower 224 bits representing the fractional part:
// target[ 255:224 ] = trunc( 1/diff ) // target[ 255:224 ] = trunc( 1/diff )
// target[ 223: 0 ] = frac( 1/diff ) // target[ 223: 0 ] = frac( 1/diff )
// //
// The 256 bit hash is exact but any floating point representation is not. // The 256 bit hash is exact but any floating point representation is not.
// Stratum provides the target difficulty as double precision, inexcact, and // Stratum provides the target difficulty as double precision, inexcact,
// which must be converted to a hash target. The converted hash target will // which must be converted to a hash target. The converted hash target will
// likely be less precise to to inexact input and conversion error. // likely be less precise due to inexact input and conversion error.
// converted to 256 bit hash which will also be inexact and likelyless
// accurate to to error in conversion.
// On the other hand getwork provides a 256 bit hash target which is exact. // On the other hand getwork provides a 256 bit hash target which is exact.
// //
// How much precision is needed? // How much precision is needed?
// //
// 128 bit types are implemented in software by the compiler using 64 bit // 128 bit types are implemented in software by the compiler on 64 bit
// hardware resulting in lower performance and more error than would be // hardware resulting in lower performance and more error than would be
// expected with a hardware 128 bit implementtaion. // expected with a hardware 128 bit implementaion.
// Float80 exploits the internals of the FP unit which provide a 64 bit // Float80 exploits the internals of the FP unit which provide a 64 bit
// mantissa in an 80 bit register with hardware rounding. When the destination // mantissa in an 80 bit register with hardware rounding. When the destination
// is double the data is rounded to float64 format. Long double returns all // is double the data is rounded to float64 format. Long double returns all
// 80 bits without rounding and including any accumulated computation error. // 80 bits without rounding and including any accumulated computation error.
// Float80 does not fit efficiently in memory. // Float80 does not fit efficiently in memory.
// //
// 256 bit hash: 76 // Significant digits:
// 256 bit hash: 76
// float: 7 (float32, 80 bits with rounding to 32 bits) // float: 7 (float32, 80 bits with rounding to 32 bits)
// double: 15 (float64, 80 bits with rounding to 64 bits) // double: 15 (float64, 80 bits with rounding to 64 bits)
// long double 19 (float80, 80 bits with no rounding) // long double: 19 (float80, 80 bits with no rounding)
// __float128 33 (128 bits with no rounding) // __float128: 33 (128 bits with no rounding)
// uint32_t: 9 // uint32_t: 9
// uint64_t: 19 // uint64_t: 19
// uint128_t 38 // uint128_t 38
// //
// The concept of significant digits doesn't apply to the 256 bit hash // The concept of significant digits doesn't apply to the 256 bit hash
// representation. It's fixed point making leading zeros significant // representation. It's fixed point making leading zeros significant,
// Leading zeros count in the 256 bit // limiting its range and precision due to fewer zon-zero significant digits.
// //
// Doing calculations with float128 and uint128 increases precision for // Doing calculations with float128 and uint128 increases precision for
// target_to_diff, but doesn't help with stratum diff being limited to // target_to_diff, but doesn't help with stratum diff being limited to
// double precision. Is the extra precision really worth the extra cost? // double precision. Is the extra precision really worth the extra cost?
// // With float128 the error rate is 1/1e33 compared with 1/1e15 for double.
// With double the error rate is 1/1e15, or one hash in every Petahash // For double that's 1 error in every petahash with a very low difficulty,
// with a very low difficulty, not a likely sitiation. Higher difficulty // not a likely situation. With higher difficulty effective precision
// increases the effective precision. Due to the floating nature of the // increases.
// decimal point leading zeros aren't counted.
// //
// Unfortunately I can't get float128 to work so long double (float80) is // Unfortunately I can't get float128 to work so long double (float80) is
// as precise as it gets. // as precise as it gets.