From dc6b007a18383dbb4270de8ee12b43952bf6ed72 Mon Sep 17 00:00:00 2001 From: Jay D Dee Date: Fri, 12 Feb 2021 15:16:53 -0500 Subject: [PATCH] v3.15.6 --- README.txt | 2 +- RELEASE_NOTES | 8 +++ algo-gate-api.c | 1 - algo/keccak/keccak-macros.c | 1 + algo/x16/x16r-4way.c | 28 +++++++---- configure | 20 ++++---- configure.ac | 2 +- cpu-miner.c | 99 ++++++++++++++++++------------------- miner.h | 11 ++--- util.c | 36 +++++++------- 10 files changed, 111 insertions(+), 97 deletions(-) diff --git a/README.txt b/README.txt index 36298c00..08c34b9d 100644 --- a/README.txt +++ b/README.txt @@ -59,7 +59,7 @@ Notes about included DLL files: Downloading DLL files from alternative sources presents an inherent 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 procedure is documented in the build instructions for Windows: https://github.com/JayDDee/cpuminer-opt/wiki/Compiling-from-source diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 1e2f27ad..9415c721 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -65,6 +65,14 @@ If not what makes it happen or not happen? 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 Fix stratum jobs lost if 2 jobs received in less than one second. diff --git a/algo-gate-api.c b/algo-gate-api.c index e407ef76..6f273ccf 100644 --- a/algo-gate-api.c +++ b/algo-gate-api.c @@ -419,7 +419,6 @@ void exec_hash_function( int algo, void *output, const void *pdata ) const char* const algo_alias_map[][2] = { // alias proper - { "argon2d-crds", "argon2d250" }, { "argon2d-dyn", "argon2d500" }, { "argon2d-uis", "argon2d4096" }, { "bcd", "x13bcd" }, diff --git a/algo/keccak/keccak-macros.c b/algo/keccak/keccak-macros.c index 64606c37..9666e7d8 100644 --- a/algo/keccak/keccak-macros.c +++ b/algo/keccak/keccak-macros.c @@ -201,6 +201,7 @@ #define IOTA(r) XOR64_IOTA(a00, a00, r) #ifdef P0 +#undef P0 #undef P1 #undef P2 #undef P3 diff --git a/algo/x16/x16r-4way.c b/algo/x16/x16r-4way.c index 4d12029d..29739525 100644 --- a/algo/x16/x16r-4way.c +++ b/algo/x16/x16r-4way.c @@ -16,8 +16,7 @@ #if defined (X16R_8WAY) -// Perform midstate prehash of hash functions with block size <= 64 bytes -// and interleave 4x64 before nonce insertion for final hash. +// Perform midstate prehash of hash functions with block size <= 72 bytes. 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_update( &x16r_ctx.jh, vdata, 64 ); 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: mm512_bswap32_intrlv80_8x64( vdata, pdata ); skein512_8way_init( &x16r_ctx.skein ); @@ -173,13 +177,13 @@ int x16r_8way_hash_generic( void* output, const void* input, int thrid ) hash7, vhash ); break; case KECCAK: - keccak512_8way_init( &ctx.keccak ); - if ( i == 0 ) - keccak512_8way_update( &ctx.keccak, input, size ); + if ( i == 0 ) + keccak512_8way_update( &ctx.keccak, input + (72<<3), 8 ); else { intrlv_8x64( vhash, in0, in1, in2, in3, in4, in5, in6, in7, size<<3 ); + keccak512_8way_init( &ctx.keccak ); keccak512_8way_update( &ctx.keccak, vhash, size ); } 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 ); s_ntime = ntime; + if ( opt_debug && !thr_id ) 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_update( &x16r_ctx.jh, vdata, 64 ); 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: mm256_bswap32_intrlv80_4x64( vdata, pdata ); 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 ); break; case KECCAK: - keccak512_4way_init( &ctx.keccak ); - if ( i == 0 ) - keccak512_4way_update( &ctx.keccak, input, size ); + if ( i == 0 ) + keccak512_4way_update( &ctx.keccak, input + (72<<2), 8 ); else { intrlv_4x64( vhash, in0, in1, in2, in3, size<<3 ); + keccak512_4way_init( &ctx.keccak ); keccak512_4way_update( &ctx.keccak, vhash, size ); } 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 ); s_ntime = ntime; 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 ); diff --git a/configure b/configure index 80d8d218..e18473f6 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # 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. @@ -577,8 +577,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='cpuminer-opt' PACKAGE_TARNAME='cpuminer-opt' -PACKAGE_VERSION='3.15.5' -PACKAGE_STRING='cpuminer-opt 3.15.5' +PACKAGE_VERSION='3.15.6' +PACKAGE_STRING='cpuminer-opt 3.15.6' PACKAGE_BUGREPORT='' 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. # This message is too long to be a string in the A/UX 3.1 sh. 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]... @@ -1404,7 +1404,7 @@ fi if test -n "$ac_init_help"; then 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 cat <<\_ACEOF @@ -1509,7 +1509,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -cpuminer-opt configure 3.15.5 +cpuminer-opt configure 3.15.6 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2012,7 +2012,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while 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 $ $0 $@ @@ -2993,7 +2993,7 @@ fi # Define the identity of the package. PACKAGE='cpuminer-opt' - VERSION='3.15.5' + VERSION='3.15.6' 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 # values after options handling. 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 CONFIG_FILES = $CONFIG_FILES @@ -6756,7 +6756,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" 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, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 31bdb562..95d825e3 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([cpuminer-opt], [3.15.5]) +AC_INIT([cpuminer-opt], [3.15.6]) AC_PREREQ([2.59c]) AC_CANONICAL_SYSTEM diff --git a/cpu-miner.c b/cpu-miner.c index 3761313f..254f38f8 100644 --- a/cpu-miner.c +++ b/cpu-miner.c @@ -490,8 +490,13 @@ static bool get_mininginfo( CURL *curl, struct work *work ) } key = json_object_get( res, "networkhashps" ); - if ( key && json_is_integer( key ) ) - net_hashrate = (double) json_integer_value( key ); + if ( 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" ); if ( key && json_is_integer( key ) ) @@ -506,26 +511,7 @@ static bool get_mininginfo( CURL *curl, struct work *work ) // complete missing data from getwork work->height = (uint32_t) net_blocks + 1; if ( work->height > g_work.height ) - { 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 } 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" ); if ( tmp ) { - if ( !json_is_string( tmp ) ) - { - applog( LOG_ERR, "JSON invalid workid" ); - goto out; - } - work->workid = strdup( json_string_value( tmp ) ); + if ( !json_is_string( tmp ) ) + { + applog( LOG_ERR, "JSON invalid workid" ); + goto out; + } + work->workid = strdup( json_string_value( tmp ) ); } rc = true; @@ -1078,13 +1064,12 @@ void report_summary_log( bool force ) if ( accepted_share_count < submitted_share_count ) { + double ltd = exp32 * last_targetdiff; double lost_ghrate = uptime.tv_sec == 0 ? 0. - : exp32 * last_targetdiff - * (double)(submitted_share_count - accepted_share_count ) - / (double)uptime.tv_sec; + : ltd * (double)(submitted_share_count - accepted_share_count ) + / (double)uptime.tv_sec; double lost_shrate = share_time == 0. ? 0. - : exp32 * last_targetdiff * (double)(submits - accepts ) - / share_time; + : ltd * (double)(submits - accepts ) / share_time; char lshr_units[4] = {0}; char lghr_units[4] = {0}; 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( bres, "B%d", solved_block_count ); - stale = work ? work->data[ algo_gate.ntime_index ] - != g_work.data[ algo_gate.ntime_index ] : false; - if ( reason ) stale = stale || strstr( reason, "job" ); + if ( reason ) + stale = strstr( reason, "job" ); + else if ( work ) + stale = work->data[ algo_gate.ntime_index ] + != g_work.data[ algo_gate.ntime_index ]; if ( stale ) { stale_share_count++; @@ -1260,14 +1247,13 @@ static int share_result( int result, struct work *work, if ( unlikely( !( opt_quiet || result || stale ) ) ) { uint32_t str[8]; + uint32_t *targ; - if ( reason ) - applog( LOG_WARNING, "Reject reason: %s", reason ); + if ( reason ) applog( LOG_WARNING, "Reject reason: %s", reason ); - // display share hash and target for troubleshooting diff_to_hash( str, my_stats.share_diff ); applog2( LOG_INFO, "Hash: %08x%08x%08x...", str[7], str[6], str[5] ); - uint32_t *targ; + if ( work ) targ = work->target; else @@ -1580,6 +1566,7 @@ static bool get_upstream_work( CURL *curl, struct work *work ) { double miner_hr = 0.; double net_hr = net_hashrate; + double nd = net_diff * exp32; char net_hr_units[4] = {0}; char miner_hr_units[4] = {0}; char net_ttf[32]; @@ -1594,11 +1581,11 @@ static bool get_upstream_work( CURL *curl, struct work *work ) pthread_mutex_unlock( &stats_lock ); if ( net_hr > 0. ) - sprintf_et( net_ttf, ( net_diff * exp32 ) / net_hr ); + sprintf_et( net_ttf, nd / net_hr ); else sprintf( net_ttf, "NA" ); if ( miner_hr > 0. ) - sprintf_et( miner_ttf, ( net_diff * exp32 ) / miner_hr ); + sprintf_et( miner_ttf, nd / miner_hr ); else sprintf( miner_ttf, "NA" ); @@ -1848,10 +1835,19 @@ bool submit_solution( struct work *work, const void *hash, work->data[ algo_gate.ntime_index ] ); } - if ( unlikely( lowdiff_debug ) ) + if ( opt_debug ) { uint32_t* h = (uint32_t*)hash; 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", 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", @@ -2066,11 +2062,12 @@ static void stratum_gen_work( struct stratum_ctx *sctx, struct work *g_work ) if ( likely( hr > 0. ) ) { + double nd = net_diff * exp32; char hr_units[4] = {0}; char block_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 ); scale_hash_for_display ( &hr, hr_units ); 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 ); 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}; 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 ) ) ) continue; - // conditional mining - if ( unlikely( !wanna_mine( thr_id ) ) ) - { - sleep(5); - continue; - } // LP_SCANTIME overrides opt_scantime option, is this right? @@ -2445,6 +2436,14 @@ static void *miner_thread( void *userdata ) #endif } } // benchmark + + // conditional mining + if ( unlikely( !wanna_mine( thr_id ) ) ) + { + sleep(5); + continue; + } + } // miner_thread loop out: diff --git a/miner.h b/miner.h index 63f17f00..119c8a75 100644 --- a/miner.h +++ b/miner.h @@ -643,7 +643,7 @@ static const char* const algo_names[] = { "lyra2z330", "m7m", "minotaur", - "myr-gr", + "myr-gr", "neoscrypt", "nist5", "pentablake", @@ -771,7 +771,7 @@ Options:\n\ allium Garlicoin (GRLC)\n\ anime Animecoin (ANI)\n\ argon2 Argon2 Coin (AR2)\n\ - argon2d250 argon2d-crds, Credits (CRDS)\n\ + argon2d250\n\ argon2d500 argon2d-dyn, Dynamic (DYN)\n\ argon2d4096 argon2d-uis, Unitus (UIS)\n\ axiom Shabal-256 MemoHash\n\ @@ -796,13 +796,13 @@ Options:\n\ lyra2h Hppcoin\n\ lyra2re lyra2\n\ lyra2rev2 lyrav2\n\ - lyra2rev3 lyrav2v3, Vertcoin\n\ + lyra2rev3 lyrav2v3\n\ lyra2z\n\ lyra2z330 Lyra2 330 rows\n\ m7m Magi (XMG)\n\ myr-gr Myriad-Groestl\n\ minotaur Ringcoin (RNG)\n\ - neoscrypt NeoScrypt(128, 2, 1)\n\ + neoscrypt NeoScrypt(128, 2, 1)\n\ nist5 Nist5\n\ pentablake 5 x blake512\n\ phi1612 phi\n\ @@ -816,7 +816,7 @@ Options:\n\ sha256d Double SHA-256\n\ sha256q Quad SHA-256, Pyrite (PYE)\n\ sha256t Triple SHA-256, Onecoin (OC)\n\ - sha3d Double Keccak256 (BSHA3)\n\ + sha3d Double Keccak256 (BSHA3)\n\ shavite3 Shavite3\n\ skein Skein+Sha (Skeincoin)\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\ long polling is unavailable, in seconds (default: 5)\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\ -m, --diff-multiplier Multiply difficulty by this factor (std is 1.0)\n\ --hash-meter Display thread hash rates\n\ diff --git a/util.c b/util.c index 5df1eb93..6a7a0503 100644 --- a/util.c +++ b/util.c @@ -1048,53 +1048,51 @@ bool fulltest( const uint32_t *hash, const uint32_t *target ) 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 -// number with the upper 32 bits representing the whole integer part and the -// lower 224 bits representing the fractional part: +// fixed point number with the upper 32 bits representing the whole integer +// part and the lower 224 bits representing the fractional part: // target[ 255:224 ] = trunc( 1/diff ) // target[ 223: 0 ] = frac( 1/diff ) // // 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 -// likely be less precise to to inexact input and conversion error. -// converted to 256 bit hash which will also be inexact and likelyless -// accurate to to error in conversion. +// likely be less precise due to inexact input and conversion error. // On the other hand getwork provides a 256 bit hash target which is exact. // // 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 -// 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 // 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 // 80 bits without rounding and including any accumulated computation error. // 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) // double: 15 (float64, 80 bits with rounding to 64 bits) -// long double 19 (float80, 80 bits with no rounding) -// __float128 33 (128 bits with no rounding) +// long double: 19 (float80, 80 bits with no rounding) +// __float128: 33 (128 bits with no rounding) // uint32_t: 9 // uint64_t: 19 // uint128_t 38 // // The concept of significant digits doesn't apply to the 256 bit hash -// representation. It's fixed point making leading zeros significant -// Leading zeros count in the 256 bit +// representation. It's fixed point making leading zeros significant, +// limiting its range and precision due to fewer zon-zero significant digits. // // Doing calculations with float128 and uint128 increases precision for // target_to_diff, but doesn't help with stratum diff being limited to // double precision. Is the extra precision really worth the extra cost? -// -// With double the error rate is 1/1e15, or one hash in every Petahash -// with a very low difficulty, not a likely sitiation. Higher difficulty -// increases the effective precision. Due to the floating nature of the -// decimal point leading zeros aren't counted. +// With float128 the error rate is 1/1e33 compared with 1/1e15 for double. +// For double that's 1 error in every petahash with a very low difficulty, +// not a likely situation. With higher difficulty effective precision +// increases. // // Unfortunately I can't get float128 to work so long double (float80) is // as precise as it gets.