Compare commits

...

2 Commits

Author SHA1 Message Date
Jay D Dee
dc6b007a18 v3.15.6 2021-02-12 15:16:53 -05:00
Jay D Dee
06bfaa1249 v3.15.5 2020-12-21 13:25:33 -05:00
16 changed files with 166 additions and 123 deletions

View File

@@ -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

View File

@@ -65,6 +65,19 @@ 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.
v3.15.4
Fixed yescryptr16 broken in v3.15.3.

View File

@@ -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" },

View File

@@ -162,7 +162,7 @@ bool ( *ready_to_mine ) ( struct work*, struct stratum_ctx*, int );
bool ( *do_this_thread ) ( int );
// After do_this_thread
void ( *resync_threads ) ( struct work* );
void ( *resync_threads ) ( int, struct work* );
// No longer needed
json_t* (*longpoll_rpc_call) ( CURL*, int*, char* );

View File

@@ -99,13 +99,13 @@ void hodl_build_block_header( struct work* g_work, uint32_t version,
// called only by thread 0, saves a backup of g_work
void hodl_get_new_work( struct work* work, struct work* g_work)
{
pthread_rwlock_rdlock( &g_work_lock );
// pthread_rwlock_rdlock( &g_work_lock );
work_free( &hodl_work );
work_copy( &hodl_work, g_work );
hodl_work.data[ algo_gate.nonce_index ] = ( clock() + rand() ) % 9999;
pthread_rwlock_unlock( &g_work_lock );
// pthread_rwlock_unlock( &g_work_lock );
}
json_t *hodl_longpoll_rpc_call( CURL *curl, int *err, char* lp_url )
@@ -125,7 +125,7 @@ json_t *hodl_longpoll_rpc_call( CURL *curl, int *err, char* lp_url )
}
// called by every thread, copies the backup to each thread's work.
void hodl_resync_threads( struct work* work )
void hodl_resync_threads( int thr_id, struct work* work )
{
int nonce_index = algo_gate.nonce_index;
pthread_barrier_wait( &hodl_barrier );
@@ -135,6 +135,7 @@ void hodl_resync_threads( struct work* work )
work_copy( work, &hodl_work );
}
work->data[ nonce_index ] = swab32( hodl_work.data[ nonce_index ] );
work_restart[thr_id].restart = 0;
}
bool hodl_do_this_thread( int thr_id )

View File

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

View File

@@ -156,7 +156,7 @@ int scanhash_zr5( struct work *work, uint32_t max_nonce,
void zr5_get_new_work( struct work* work, struct work* g_work, int thr_id,
uint32_t* end_nonce_ptr )
{
pthread_rwlock_rdlock( &g_work_lock );
// pthread_rwlock_rdlock( &g_work_lock );
// ignore POK in first word
const int wkcmp_sz = 72; // (19-1) * sizeof(uint32_t)
@@ -174,7 +174,7 @@ void zr5_get_new_work( struct work* work, struct work* g_work, int thr_id,
else
++(*nonceptr);
pthread_rwlock_unlock( &g_work_lock );
// pthread_rwlock_unlock( &g_work_lock );
}
void zr5_display_pok( struct work* work )

View File

@@ -912,7 +912,7 @@ extern void hmq1725_4way_hash(void *state, const void *input)
sph_whirlpool512_full( &ctx.whirlpool, hash2, hash2, 64 );
sph_whirlpool512_full( &ctx.whirlpool, hash3, hash3, 64 );
// A = fugue serial, B = sha512 prarallel
// A = fugue serial, B = sha512 parallel
intrlv_4x64( vhash, hash0, hash1, hash2, hash3, 512 );

View File

@@ -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 );

View File

@@ -259,15 +259,24 @@ static inline void salsa20_simd_unshuffle(const salsa20_blk_t *Bin,
#define WRITE_X(out) \
(out).q[0] = X0; (out).q[1] = X1; (out).q[2] = X2; (out).q[3] = X3;
#ifdef __XOP__
#if defined(__AVX512VL__)
#define ARX(out, in1, in2, s) \
out = _mm_xor_si128(out, _mm_rol_epi32(_mm_add_epi32(in1, in2), s));
#elif defined(__XOP__)
#define ARX(out, in1, in2, s) \
out = _mm_xor_si128(out, _mm_roti_epi32(_mm_add_epi32(in1, in2), s));
#else
#define ARX(out, in1, in2, s) { \
__m128i tmp = _mm_add_epi32(in1, in2); \
out = _mm_xor_si128(out, _mm_slli_epi32(tmp, s)); \
out = _mm_xor_si128(out, _mm_srli_epi32(tmp, 32 - s)); \
}
#endif
#define SALSA20_2ROUNDS \

View File

@@ -165,6 +165,7 @@ static inline void salsa20_simd_unshuffle(const salsa20_blk_t *Bin,
}
#ifdef __SSE2__
#define DECL_X \
__m128i X0, X1, X2, X3;
#define DECL_Y \
@@ -174,15 +175,24 @@ static inline void salsa20_simd_unshuffle(const salsa20_blk_t *Bin,
#define WRITE_X(out) \
(out).q[0] = X0; (out).q[1] = X1; (out).q[2] = X2; (out).q[3] = X3;
#ifdef __XOP__
#if defined(__AVX512VL__)
#define ARX(out, in1, in2, s) \
out = _mm_xor_si128(out, _mm_rol_epi32(_mm_add_epi32(in1, in2), s));
#elif defined(__XOP__)
#define ARX(out, in1, in2, s) \
out = _mm_xor_si128(out, _mm_roti_epi32(_mm_add_epi32(in1, in2), s));
#else
#define ARX(out, in1, in2, s) { \
__m128i tmp = _mm_add_epi32(in1, in2); \
out = _mm_xor_si128(out, _mm_slli_epi32(tmp, s)); \
out = _mm_xor_si128(out, _mm_srli_epi32(tmp, 32 - s)); \
}
#endif
#define SALSA20_2ROUNDS \

20
configure vendored
View File

@@ -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.4.
# 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.4'
PACKAGE_STRING='cpuminer-opt 3.15.4'
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.4 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.4:";;
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.4
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.4, 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.4'
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.4, 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.4
cpuminer-opt config.status 3.15.6
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"

View File

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

View File

@@ -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, "Invalid job id" );
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 @@ start:
{
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 @@ start:
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",
@@ -1956,8 +1952,6 @@ void std_get_new_work( struct work* work, struct work* g_work, int thr_id,
uint32_t *nonceptr = work->data + algo_gate.nonce_index;
bool force_new_work = false;
pthread_rwlock_rdlock( &g_work_lock );
if ( have_stratum )
force_new_work = work->job_id ? strtoul( work->job_id, NULL, 16 )
!= strtoul( g_work->job_id, NULL, 16 )
@@ -1973,8 +1967,6 @@ void std_get_new_work( struct work* work, struct work* g_work, int thr_id,
}
else
++(*nonceptr);
pthread_rwlock_unlock( &g_work_lock );
}
bool std_ready_to_mine( struct work* work, struct stratum_ctx* stratum,
@@ -1990,13 +1982,14 @@ bool std_ready_to_mine( struct work* work, struct stratum_ctx* stratum,
static void stratum_gen_work( struct stratum_ctx *sctx, struct work *g_work )
{
// Safer than testing the job id
bool new_job = *get_stratum_job_ntime()
!= g_work->data[ algo_gate.ntime_index ];
bool new_job;
pthread_rwlock_wrlock( &g_work_lock );
pthread_mutex_lock( &sctx->work_lock );
new_job = sctx->new_job;
sctx->new_job = false;
free( g_work->job_id );
g_work->job_id = strdup( sctx->job.job_id );
g_work->xnonce2_len = sctx->xnonce2_size;
@@ -2009,8 +2002,12 @@ static void stratum_gen_work( struct stratum_ctx *sctx, struct work *g_work )
g_work->targetdiff = sctx->job.diff
/ ( opt_target_factor * opt_diff_factor );
diff_to_hash( g_work->target, g_work->targetdiff );
// Increment extranonce2
for ( int t = 0; t < sctx->xnonce2_size && !( ++sctx->job.xnonce2[t] ); t++ );
for ( int t = 0;
t < sctx->xnonce2_size && !( ++sctx->job.xnonce2[t] );
t++ );
g_work_time = time(NULL);
restart_threads();
@@ -2032,7 +2029,7 @@ static void stratum_gen_work( struct stratum_ctx *sctx, struct work *g_work )
else if ( last_block_height != sctx->block_height )
applog( LOG_BLUE, "New Block %d, Job %s",
sctx->block_height, g_work->job_id );
else if ( new_job && g_work->job_id )
else if ( g_work->job_id && new_job )
applog( LOG_BLUE, "New Work: Block %d, Net diff %.5g, Job %s",
sctx->block_height, net_diff, g_work->job_id );
else if ( !opt_quiet )
@@ -2065,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",
@@ -2085,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 );
@@ -2240,19 +2238,18 @@ static void *miner_thread( void *userdata )
pthread_rwlock_unlock( &g_work_lock );
}
pthread_rwlock_rdlock( &g_work_lock );
algo_gate.get_new_work( &work, &g_work, thr_id, &end_nonce );
work_restart[thr_id].restart = 0;
pthread_rwlock_unlock( &g_work_lock );
} // do_this_thread
algo_gate.resync_threads( &work );
algo_gate.resync_threads( thr_id, &work );
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?
@@ -2309,7 +2306,6 @@ static void *miner_thread( void *userdata )
// init time
if ( firstwork_time == 0 )
firstwork_time = time(NULL);
work_restart[thr_id].restart = 0;
hashes_done = 0;
gettimeofday( (struct timeval *) &tv_start, NULL );
@@ -2440,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:
@@ -2731,7 +2735,6 @@ static void *stratum_thread(void *userdata )
pthread_rwlock_wrlock( &g_work_lock );
g_work_time = 0;
pthread_rwlock_unlock( &g_work_lock );
// restart_threads();
if ( !stratum_connect( &stratum, stratum.url )
|| !stratum_subscribe( &stratum )
|| !stratum_authorize( &stratum, rpc_user, rpc_pass ) )
@@ -2757,9 +2760,7 @@ static void *stratum_thread(void *userdata )
report_summary_log( ( stratum_diff != stratum.job.diff )
&& ( stratum_diff != 0. ) );
if ( stratum.job.job_id && ( !g_work_time
|| ( *get_stratum_job_ntime()
!= g_work.data[ algo_gate.ntime_index ] ) ) )
if ( stratum.new_job )
stratum_gen_work( &stratum, &g_work );
if ( likely( stratum_socket_full( &stratum, opt_timeout ) ) )

14
miner.h
View File

@@ -444,7 +444,8 @@ struct stratum_ctx {
struct work work __attribute__ ((aligned (64)));
pthread_mutex_t work_lock;
int block_height;
int block_height;
bool new_job;
} __attribute__ ((aligned (64)));
bool stratum_socket_full(struct stratum_ctx *sctx, int timeout);
@@ -642,7 +643,7 @@ static const char* const algo_names[] = {
"lyra2z330",
"m7m",
"minotaur",
"myr-gr",
"myr-gr",
"neoscrypt",
"nist5",
"pentablake",
@@ -770,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\
@@ -795,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\
@@ -815,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\
@@ -874,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\

39
util.c
View File

@@ -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.
@@ -2172,7 +2170,8 @@ bool stratum_handle_method(struct stratum_ctx *sctx, const char *s)
if (!strcasecmp(method, "mining.notify")) {
ret = stratum_notify(sctx, params);
goto out;
sctx->new_job = true;
goto out;
}
if (!strcasecmp(method, "mining.ping")) { // cgminer 4.7.1+
if (opt_debug) applog(LOG_DEBUG, "Pool ping");