This commit is contained in:
Jay D Dee
2020-01-23 00:11:08 -05:00
parent 1a7a573675
commit 103e6ad36c
12 changed files with 329 additions and 285 deletions

View File

@@ -33,3 +33,6 @@ Jay D Dee
xcouiz@gmail.com xcouiz@gmail.com
Cryply Cryply
Colin Percival
Alexander Peslyak

View File

@@ -65,6 +65,13 @@ If not what makes it happen or not happen?
Change Log Change Log
---------- ----------
v3.11.6
Fixed CPU temperature regression from v3.11.5.
More improvements to share log. More compact, highlight incremented counter,
block height when solved, job id when stale.
v3.11.5 v3.11.5
Fixed AVX512 detection that could cause compilation errors on CPUs Fixed AVX512 detection that could cause compilation errors on CPUs

View File

@@ -320,18 +320,19 @@ bool init_allium_8way_ctx()
return true; return true;
} }
void allium_8way_hash( void *state, const void *input ) void allium_8way_hash( void *hash, const void *input )
{ {
uint32_t vhashA[8*8] __attribute__ ((aligned (64))); uint64_t vhashA[4*8] __attribute__ ((aligned (64)));
uint32_t vhashB[8*8] __attribute__ ((aligned (64))); uint64_t vhashB[4*8] __attribute__ ((aligned (64)));
uint32_t hash0[8] __attribute__ ((aligned (32))); // uint64_t hash[4*8] __attribute__ ((aligned (64)));
uint32_t hash1[8] __attribute__ ((aligned (32))); uint64_t *hash0 = (uint64_t*)hash;
uint32_t hash2[8] __attribute__ ((aligned (32))); uint64_t *hash1 = (uint64_t*)hash+ 4;
uint32_t hash3[8] __attribute__ ((aligned (32))); uint64_t *hash2 = (uint64_t*)hash+ 8;
uint32_t hash4[8] __attribute__ ((aligned (64))); uint64_t *hash3 = (uint64_t*)hash+12;
uint32_t hash5[8] __attribute__ ((aligned (32))); uint64_t *hash4 = (uint64_t*)hash+16;
uint32_t hash6[8] __attribute__ ((aligned (32))); uint64_t *hash5 = (uint64_t*)hash+20;
uint32_t hash7[8] __attribute__ ((aligned (32))); uint64_t *hash6 = (uint64_t*)hash+24;
uint64_t *hash7 = (uint64_t*)hash+28;
allium_8way_ctx_holder ctx __attribute__ ((aligned (64))); allium_8way_ctx_holder ctx __attribute__ ((aligned (64)));
memcpy( &ctx, &allium_8way_ctx, sizeof(allium_8way_ctx) ); memcpy( &ctx, &allium_8way_ctx, sizeof(allium_8way_ctx) );
@@ -398,69 +399,74 @@ void allium_8way_hash( void *state, const void *input )
dintrlv_4x64( hash0, hash1, hash2, hash3, vhashA, 256 ); dintrlv_4x64( hash0, hash1, hash2, hash3, vhashA, 256 );
dintrlv_4x64( hash4, hash5, hash6, hash7, vhashB, 256 ); dintrlv_4x64( hash4, hash5, hash6, hash7, vhashB, 256 );
update_and_final_groestl256( &ctx.groestl, state, hash0, 256 ); update_and_final_groestl256( &ctx.groestl, hash0, hash0, 256 );
memcpy( &ctx.groestl, &allium_8way_ctx.groestl, memcpy( &ctx.groestl, &allium_8way_ctx.groestl,
sizeof(hashState_groestl256) ); sizeof(hashState_groestl256) );
update_and_final_groestl256( &ctx.groestl, state+32, hash1, 256 ); update_and_final_groestl256( &ctx.groestl, hash1, hash1, 256 );
memcpy( &ctx.groestl, &allium_8way_ctx.groestl, memcpy( &ctx.groestl, &allium_8way_ctx.groestl,
sizeof(hashState_groestl256) ); sizeof(hashState_groestl256) );
update_and_final_groestl256( &ctx.groestl, state+64, hash2, 256 ); update_and_final_groestl256( &ctx.groestl, hash2, hash2, 256 );
memcpy( &ctx.groestl, &allium_8way_ctx.groestl, memcpy( &ctx.groestl, &allium_8way_ctx.groestl,
sizeof(hashState_groestl256) ); sizeof(hashState_groestl256) );
update_and_final_groestl256( &ctx.groestl, state+96, hash3, 256 ); update_and_final_groestl256( &ctx.groestl, hash3, hash3, 256 );
memcpy( &ctx.groestl, &allium_8way_ctx.groestl, memcpy( &ctx.groestl, &allium_8way_ctx.groestl,
sizeof(hashState_groestl256) ); sizeof(hashState_groestl256) );
update_and_final_groestl256( &ctx.groestl, state+128, hash4, 256 ); update_and_final_groestl256( &ctx.groestl, hash4, hash4, 256 );
memcpy( &ctx.groestl, &allium_8way_ctx.groestl, memcpy( &ctx.groestl, &allium_8way_ctx.groestl,
sizeof(hashState_groestl256) ); sizeof(hashState_groestl256) );
update_and_final_groestl256( &ctx.groestl, state+160, hash5, 256 ); update_and_final_groestl256( &ctx.groestl, hash5, hash5, 256 );
memcpy( &ctx.groestl, &allium_8way_ctx.groestl, memcpy( &ctx.groestl, &allium_8way_ctx.groestl,
sizeof(hashState_groestl256) ); sizeof(hashState_groestl256) );
update_and_final_groestl256( &ctx.groestl, state+192, hash6, 256 ); update_and_final_groestl256( &ctx.groestl, hash6, hash6, 256 );
memcpy( &ctx.groestl, &allium_8way_ctx.groestl, memcpy( &ctx.groestl, &allium_8way_ctx.groestl,
sizeof(hashState_groestl256) ); sizeof(hashState_groestl256) );
update_and_final_groestl256( &ctx.groestl, state+224, hash7, 256 ); update_and_final_groestl256( &ctx.groestl, hash7, hash7, 256 );
} }
int scanhash_allium_8way( struct work *work, uint32_t max_nonce, int scanhash_allium_8way( struct work *work, uint32_t max_nonce,
uint64_t *hashes_done, struct thr_info *mythr ) uint64_t *hashes_done, struct thr_info *mythr )
{ {
uint32_t hash[8*8] __attribute__ ((aligned (64))); uint64_t hash[4*8] __attribute__ ((aligned (64)));
uint32_t vdata[20*8] __attribute__ ((aligned (64))); uint32_t vdata[20*8] __attribute__ ((aligned (64)));
uint32_t *pdata = work->data; uint32_t *pdata = work->data;
uint32_t *ptarget = work->target; uint64_t *ptarget = (uint64_t*)work->target;
const uint32_t first_nonce = pdata[19]; const uint32_t first_nonce = pdata[19];
const uint32_t last_nonce = max_nonce - 8; const uint32_t last_nonce = max_nonce - 8;
uint32_t n = first_nonce; uint32_t n = first_nonce;
const uint32_t Htarg = ptarget[7]; const uint64_t Htarg = ptarget[3];
__m256i *noncev = (__m256i*)vdata + 19; // aligned __m256i *noncev = (__m256i*)vdata + 19; // aligned
int thr_id = mythr->id; const int thr_id = mythr->id;
const bool bench = opt_benchmark;
if ( opt_benchmark ) if unlikely( bench )
( (uint32_t*)ptarget )[7] = 0x0000ff; ( (uint32_t*)ptarget )[7] = 0x0000ff;
mm256_bswap32_intrlv80_8x32( vdata, pdata ); mm256_bswap32_intrlv80_8x32( vdata, pdata );
*noncev = _mm256_set_epi32( n+7, n+6, n+5, n+4, n+3, n+2, n+1, n );
blake256_8way_init( &allium_8way_ctx.blake ); blake256_8way_init( &allium_8way_ctx.blake );
blake256_8way_update( &allium_8way_ctx.blake, vdata, 64 ); blake256_8way_update( &allium_8way_ctx.blake, vdata, 64 );
do { do {
*noncev = mm256_bswap_32( _mm256_set_epi32( n+7, n+6, n+5, n+4,
n+3, n+2, n+1, n ) );
allium_8way_hash( hash, vdata ); allium_8way_hash( hash, vdata );
pdata[19] = n;
for ( int lane = 0; lane < 8; lane++ ) if ( (hash+(lane<<3))[7] <= Htarg ) for ( int lane = 0; lane < 8; lane++ )
{ {
if ( fulltest( hash+(lane<<3), ptarget ) && !opt_benchmark ) const uint64_t *lane_hash = hash + (lane<<2);
if unlikely( lane_hash[3] <= Htarg )
{ {
pdata[19] = n + lane; if likely( ( lane_hash[3] < Htarg && !bench )
submit_lane_solution( work, hash+(lane<<3), mythr, lane ); || valid_hash( lane_hash, ptarget ) )
{
pdata[19] = bswap_32( n + lane );
submit_lane_solution( work, lane_hash, mythr, lane );
} }
}
} }
n += 8; n += 8;
} while ( (n < last_nonce) && !work_restart[thr_id].restart); *noncev = _mm256_add_epi32( *noncev, m256_const1_32( 8 ) );
} while likely( (n <= last_nonce) && !work_restart[thr_id].restart );
pdata[19] = n;
*hashes_done = n - first_nonce; *hashes_done = n - first_nonce;
return 0; return 0;
} }

View File

@@ -267,8 +267,13 @@ int scanhash_m7m_hash( struct work* work, uint64_t max_nonce,
SHA256_Final( (unsigned char*) hash, &ctxf_sha256 ); SHA256_Final( (unsigned char*) hash, &ctxf_sha256 );
} }
if ( unlikely( hash[7] <= ptarget[7] ) )
if ( likely( fulltest( hash, ptarget ) && !opt_benchmark ) ) if ( unlikely( valid_hash( (uint64_t*)hash, (uint64_t*)ptarget )
&& !opt_benchmark ) )
// if ( unlikely( hash[7] <= ptarget[7] ) )
// if ( likely( fulltest( hash, ptarget ) && !opt_benchmark ) )
{ {
if ( opt_debug ) if ( opt_debug )
{ {

View File

@@ -351,7 +351,7 @@ typedef union _x17_4way_context_overlay x17_4way_context_overlay;
void x17_4way_hash( void *state, const void *input ) void x17_4way_hash( void *state, const void *input )
{ {
uint64_t vhash[8*4] __attribute__ ((aligned (128))); uint64_t vhash[8*4] __attribute__ ((aligned (64)));
uint64_t vhashA[8*4] __attribute__ ((aligned (64))); uint64_t vhashA[8*4] __attribute__ ((aligned (64)));
uint64_t vhashB[8*4] __attribute__ ((aligned (64))); uint64_t vhashB[8*4] __attribute__ ((aligned (64)));
uint64_t hash0[8] __attribute__ ((aligned (64))); uint64_t hash0[8] __attribute__ ((aligned (64)));
@@ -471,8 +471,8 @@ void x17_4way_hash( void *state, const void *input )
int scanhash_x17_4way( struct work *work, uint32_t max_nonce, int scanhash_x17_4way( struct work *work, uint32_t max_nonce,
uint64_t *hashes_done, struct thr_info *mythr ) uint64_t *hashes_done, struct thr_info *mythr )
{ {
uint32_t hash[16*4] __attribute__ ((aligned (128))); uint32_t hash[16*4] __attribute__ ((aligned (64)));
uint32_t vdata[24*4] __attribute__ ((aligned (64))); uint32_t vdata[20*4] __attribute__ ((aligned (64)));
uint32_t lane_hash[8] __attribute__ ((aligned (64))); uint32_t lane_hash[8] __attribute__ ((aligned (64)));
uint32_t *hash7 = &(hash[7<<2]); uint32_t *hash7 = &(hash[7<<2]);
uint32_t *pdata = work->data; uint32_t *pdata = work->data;
@@ -483,27 +483,30 @@ int scanhash_x17_4way( struct work *work, uint32_t max_nonce,
uint32_t n = first_nonce; uint32_t n = first_nonce;
const int thr_id = mythr->id; const int thr_id = mythr->id;
const uint32_t Htarg = ptarget[7]; const uint32_t Htarg = ptarget[7];
const bool bench = opt_benchmark;
mm256_bswap32_intrlv80_4x64( vdata, pdata ); mm256_bswap32_intrlv80_4x64( vdata, pdata );
*noncev = mm256_intrlv_blend_32(
_mm256_set_epi32( n+3, 0, n+2, 0, n+1, 0, n, 0 ), *noncev );
do do
{ {
*noncev = mm256_intrlv_blend_32( mm256_bswap_32(
_mm256_set_epi32( n+3, 0, n+2, 0, n+1, 0, n, 0 ) ), *noncev );
x17_4way_hash( hash, vdata ); x17_4way_hash( hash, vdata );
for ( int lane = 0; lane < 4; lane++ ) for ( int lane = 0; lane < 4; lane++ )
if unlikely( ( hash7[ lane ] <= Htarg ) ) if ( unlikely( hash7[ lane ] <= Htarg && !bench ) )
{ {
extr_lane_4x32( lane_hash, hash, lane, 256 ); extr_lane_4x32( lane_hash, hash, lane, 256 );
if ( likely( fulltest( lane_hash, ptarget ) && !opt_benchmark ) ) if ( ( hash7[ lane ] < Htarg ) || valid_hash( lane_hash, ptarget ) )
{ {
pdata[19] = n + lane; pdata[19] = bswap_32( n + lane );
submit_lane_solution( work, lane_hash, mythr, lane ); submit_lane_solution( work, lane_hash, mythr, lane );
} }
} }
*noncev = _mm256_add_epi32( *noncev,
m256_const1_64( 0x0000000400000000 ) );
n += 4; n += 4;
} while ( likely( ( n < last_nonce ) && !work_restart[thr_id].restart ) ); } while ( likely( ( n <= last_nonce ) && !work_restart[thr_id].restart ) );
pdata[19] = n;
*hashes_done = n - first_nonce; *hashes_done = n - first_nonce;
return 0; return 0;
} }

View File

@@ -135,7 +135,7 @@ bool register_yespower_algo( algo_gate_t* gate )
if ( yespower_params.pers ) if ( yespower_params.pers )
applog( LOG_NOTICE,"Key= \"%s\"\n", yespower_params.pers ); applog( LOG_NOTICE,"Key= \"%s\"\n", yespower_params.pers );
gate->optimizations = SSE2_OPT; gate->optimizations = SSE2_OPT | SHA_OPT;
gate->scanhash = (void*)&scanhash_yespower; gate->scanhash = (void*)&scanhash_yespower;
gate->hash = (void*)&yespower_hash; gate->hash = (void*)&yespower_hash;
opt_target_factor = 65536.0; opt_target_factor = 65536.0;
@@ -149,7 +149,7 @@ bool register_yespowerr16_algo( algo_gate_t* gate )
yespower_params.r = 16; yespower_params.r = 16;
yespower_params.pers = NULL; yespower_params.pers = NULL;
yespower_params.perslen = 0; yespower_params.perslen = 0;
gate->optimizations = SSE2_OPT; gate->optimizations = SSE2_OPT | SHA_OPT;
gate->scanhash = (void*)&scanhash_yespower; gate->scanhash = (void*)&scanhash_yespower;
gate->hash = (void*)&yespower_hash; gate->hash = (void*)&yespower_hash;
opt_target_factor = 65536.0; opt_target_factor = 65536.0;
@@ -223,7 +223,7 @@ bool register_power2b_algo( algo_gate_t* gate )
applog( LOG_NOTICE,"Key= \"%s\"", yespower_params.pers ); applog( LOG_NOTICE,"Key= \"%s\"", yespower_params.pers );
applog( LOG_NOTICE,"Key length= %d\n", yespower_params.perslen ); applog( LOG_NOTICE,"Key length= %d\n", yespower_params.perslen );
gate->optimizations = SSE2_OPT; gate->optimizations = SSE2_OPT | SHA_OPT;
gate->scanhash = (void*)&scanhash_yespower_b2b; gate->scanhash = (void*)&scanhash_yespower_b2b;
gate->hash = (void*)&yespower_b2b_hash; gate->hash = (void*)&yespower_b2b_hash;
opt_target_factor = 65536.0; opt_target_factor = 65536.0;

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.11.5. # Generated by GNU Autoconf 2.69 for cpuminer-opt 3.11.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.11.5' PACKAGE_VERSION='3.11.6'
PACKAGE_STRING='cpuminer-opt 3.11.5' PACKAGE_STRING='cpuminer-opt 3.11.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.11.5 to adapt to many kinds of systems. \`configure' configures cpuminer-opt 3.11.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.11.5:";; short | recursive ) echo "Configuration of cpuminer-opt 3.11.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.11.5 cpuminer-opt configure 3.11.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.11.5, which was It was created by cpuminer-opt $as_me 3.11.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.11.5' VERSION='3.11.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.11.5, which was This file was extended by cpuminer-opt $as_me 3.11.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.11.5 cpuminer-opt config.status 3.11.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.11.5]) AC_INIT([cpuminer-opt], [3.11.6])
AC_PREREQ([2.59c]) AC_PREREQ([2.59c])
AC_CANONICAL_SYSTEM AC_CANONICAL_SYSTEM

View File

@@ -820,20 +820,15 @@ out:
// returns the unit prefix and the hashrate appropriately scaled. // returns the unit prefix and the hashrate appropriately scaled.
void scale_hash_for_display ( double* hashrate, char* prefix ) void scale_hash_for_display ( double* hashrate, char* prefix )
{ {
if ( *hashrate < 1e4 ) // 0 H/s to 9999 h/s if ( *hashrate < 1e4 ) *prefix = 0;
*prefix = 0; else if ( *hashrate < 1e7 ) { *prefix = 'k'; *hashrate /= 1e3; }
else if ( *hashrate < 1e7 ) // 10 kH/s to 9999 kh/s else if ( *hashrate < 1e10 ) { *prefix = 'M'; *hashrate /= 1e6; }
{ *prefix = 'k'; *hashrate /= 1e3; } else if ( *hashrate < 1e13 ) { *prefix = 'G'; *hashrate /= 1e9; }
else if ( *hashrate < 1e10 ) // 10 Mh/s to 9999 Mh/s else if ( *hashrate < 1e16 ) { *prefix = 'T'; *hashrate /= 1e12; }
{ *prefix = 'M'; *hashrate /= 1e6; } else if ( *hashrate < 1e19 ) { *prefix = 'P'; *hashrate /= 1e15; }
else if ( *hashrate < 1e13 ) // 10 Gh/s to 9999 Gh/s else if ( *hashrate < 1e22 ) { *prefix = 'E'; *hashrate /= 1e18; }
{ *prefix = 'G'; *hashrate /= 1e9; } else if ( *hashrate < 1e25 ) { *prefix = 'Z'; *hashrate /= 1e21; }
else if ( *hashrate < 1e16 ) // 10 Th/s to 9999 Th/s else { *prefix = 'Y'; *hashrate /= 1e24; }
{ *prefix = 'T'; *hashrate /= 1e12; }
else if ( *hashrate < 1e19 ) // 10 Ph/s to 9999 Ph
{ *prefix = 'P'; *hashrate /= 1e15; }
else // 10 Eh/s and higher
{ *prefix = 'E'; *hashrate /= 1e18; }
} }
static inline void sprintf_et( char *str, int seconds ) static inline void sprintf_et( char *str, int seconds )
@@ -842,10 +837,13 @@ static inline void sprintf_et( char *str, int seconds )
unsigned int min = seconds / 60; unsigned int min = seconds / 60;
unsigned int sec = seconds % 60; unsigned int sec = seconds % 60;
unsigned int hrs = min / 60; unsigned int hrs = min / 60;
if ( hrs ) if ( unlikely( hrs ) )
{ {
unsigned int years = hrs / (24*365);
unsigned int days = hrs / 24; unsigned int days = hrs / 24;
if ( days ) //0d00h if ( years )
sprintf( str, "%uy%ud", years, years % 365 );
else if ( days ) //0d00h
sprintf( str, "%ud%02uh", days, hrs % 24 ); sprintf( str, "%ud%02uh", days, hrs % 24 );
else // 0h00m else // 0h00m
sprintf( str, "%uh%02um", hrs, min % 60 ); sprintf( str, "%uh%02um", hrs, min % 60 );
@@ -867,6 +865,7 @@ const double diff_to_hash = 4294967296.;
static struct timeval session_start; static struct timeval session_start;
static struct timeval five_min_start; static struct timeval five_min_start;
static uint64_t session_first_block = 0;
static double latency_sum = 0.; static double latency_sum = 0.;
static uint64_t submit_sum = 0; static uint64_t submit_sum = 0;
static uint64_t accept_sum = 0; static uint64_t accept_sum = 0;
@@ -874,7 +873,7 @@ static uint64_t stale_sum = 0;
static uint64_t reject_sum = 0; static uint64_t reject_sum = 0;
static double norm_diff_sum = 0.; static double norm_diff_sum = 0.;
static uint32_t last_block_height = 0; static uint32_t last_block_height = 0;
static bool new_job = false; //static bool new_job = false;
static double last_targetdiff = 0.; static double last_targetdiff = 0.;
static double ref_rate_hi = 0.; static double ref_rate_hi = 0.;
static double ref_rate_lo = 1e100; static double ref_rate_lo = 1e100;
@@ -1019,15 +1018,18 @@ static int share_result( int result, struct work *null_work,
int latency = 0; int latency = 0;
struct share_stats_t my_stats = {0}; struct share_stats_t my_stats = {0};
struct timeval ack_time, latency_tv, et; struct timeval ack_time, latency_tv, et;
const char *sres = NULL; char ares[48];
char job_id[48]; char sres[48];
char rres[48];
char bres[48];
// char job_id[48];
bool solved = false; bool solved = false;
bool stale = false; bool stale = false;
char *acol = NULL, *bcol = NULL, *scol = NULL, *rcol = NULL; char *acol = NULL, *bcol = NULL, *scol = NULL, *rcol = NULL;
// Mutex while we grab a snapshot of the stats. // Mutex while we grab a snapshot of the stats.
pthread_mutex_lock( &stats_lock ); pthread_mutex_lock( &stats_lock );
if ( share_stats[ s_get_ptr ].submit_time.tv_sec ) if ( likely( share_stats[ s_get_ptr ].submit_time.tv_sec ) )
{ {
memcpy( &my_stats, &share_stats[ s_get_ptr], sizeof my_stats ); memcpy( &my_stats, &share_stats[ s_get_ptr], sizeof my_stats );
memset( &share_stats[ s_get_ptr ], 0, sizeof my_stats ); memset( &share_stats[ s_get_ptr ], 0, sizeof my_stats );
@@ -1077,7 +1079,6 @@ static int share_result( int result, struct work *null_work,
rejected_share_count++; rejected_share_count++;
} }
// update global counters for summary report // update global counters for summary report
pthread_mutex_lock( &stats_lock ); pthread_mutex_lock( &stats_lock );
@@ -1102,65 +1103,70 @@ static int share_result( int result, struct work *null_work,
pthread_mutex_unlock( &stats_lock ); pthread_mutex_unlock( &stats_lock );
sprintf( job_id, "job %s", my_stats.job_id );
bcol = acol = scol = rcol = "\0"; bcol = acol = scol = rcol = "\0";
if ( likely( result ) )
{
if ( unlikely( solved ) )
{
sprintf( bres, "BLOCK SOLVED %d", solved_block_count );
sprintf( ares, "A%d", accepted_share_count );
}
else
{
sprintf( bres, "B%d", solved_block_count );
sprintf( ares, "Accepted %d", accepted_share_count );
}
sprintf( sres, "S%d", stale_share_count );
sprintf( rres, "R%d", rejected_share_count );
}
else
{
sprintf( ares, "A%d", accepted_share_count );
sprintf( bres, "B%d", solved_block_count );
if ( stale )
{
sprintf( sres, "Stale job %d", stale_share_count );
sprintf( rres, "R%d", rejected_share_count );
}
else
{
sprintf( sres, "S%d", stale_share_count );
sprintf( rres, "Rejected %d" , rejected_share_count );
}
}
bcol = acol = scol = rcol = CL_WHT;
if ( use_colors ) if ( use_colors )
{ {
if ( likely( result ) ) if ( likely( result ) )
{ {
if ( unlikely( solved ) ) if ( unlikely( solved ) )
{ {
sres = CL_MAG "BLOCK SOLVED" CL_WHT;
bcol = CL_MAG;
}
else
sres = CL_GRN "Accepted" CL_WHT;
acol = CL_GRN;
}
/*
if ( unlikely( solved ) )
{
sres = CL_MAG "BLOCK SOLVED" CL_WHT;
bcol = CL_MAG; bcol = CL_MAG;
acol = CL_GRN; acol = CL_GRN;
} }
else if ( likely( result ) ) else
{ acol = CL_GRN;
sres = CL_GRN "Accepted" CL_WHT; }
acol = CL_GRN; else if ( stale )
} scol = CL_YL2;
*/ else
else if ( stale ) rcol = CL_RED;
{
sres = CL_YL2 "Stale share" CL_WHT;
scol = CL_YL2;
sprintf( job_id, "%sjob %s%s", CL_YL2, my_stats.job_id, CL_N );
}
else
{
sres = CL_RED "Rejected" CL_WHT;
rcol = CL_RED;
}
} }
else // monochrome
sres = solved ? "BLOCK SOLVED"
: ( result ? "Accepted"
: stale ? "Stale share" : "Rejected" );
applog( LOG_NOTICE, "%d: %s, %.3f secs (%dms), %sA:%d" CL_WHT " %sS:%d" CL_WHT " %sR:%d" CL_WHT " %sB:%d" CL_WHT, applog( LOG_NOTICE, "%d %s%s %s%s %s%s %s%s" CL_WHT ", %.3f sec (%dms)",
my_stats.share_count, sres, share_time, latency, acol, my_stats.share_count, acol, ares, scol, sres, rcol, rres, bcol,
accepted_share_count, scol, stale_share_count, rcol, bres, share_time, latency );
rejected_share_count, bcol, solved_block_count );
if ( have_stratum && !opt_quiet ) if ( have_stratum && !opt_quiet )
applog2( LOG_INFO, "Share diff %.3g (%5f%%), block %d, %s", applog2( LOG_NOTICE, "Diff %.3g (%.3g%), %sBlock %d, %sJob %s" CL_WHT,
my_stats.share_diff, share_ratio, stratum.block_height, my_stats.share_diff, share_ratio, bcol, stratum.block_height,
job_id ); scol, my_stats.job_id );
if ( unlikely( reason && !result ) ) if ( unlikely( reason && !result ) )
{ {
if ( !opt_quiet && !stale ) if ( !( opt_quiet || stale ) )
applog( LOG_WARNING, "Reject reason: %s", reason ); applog( LOG_WARNING, "Reject reason: %s", reason );
if ( opt_debug ) if ( opt_debug )
@@ -1695,7 +1701,7 @@ static void *workio_thread(void *userdata)
if ( jsonrpc_2 && !have_stratum ) if ( jsonrpc_2 && !have_stratum )
ok = rpc2_workio_login( curl ); ok = rpc2_workio_login( curl );
while (ok) while ( likely(ok) )
{ {
struct workio_cmd *wc; struct workio_cmd *wc;
@@ -1771,7 +1777,8 @@ static bool get_work(struct thr_info *thr, struct work *work)
return true; return true;
} }
static bool submit_work( struct thr_info *thr, const struct work *work_in ) static bool submit_work( const struct thr_info *thr,
const struct work *work_in )
{ {
struct workio_cmd *wc; struct workio_cmd *wc;
@@ -1795,20 +1802,22 @@ err_out:
return false; return false;
} }
// Convert little endian 256 bit unsigned integer to // __float128?
// double precision floating point. // Convert little endian 256 bit (38 decimal digits) unsigned integer to
static inline double u256_to_double( const uint64_t* u ) // double precision floating point with 15 decimal digits precision.
// returns u * ( 2**256 )
static inline double u256_to_double( const uint64_t *u )
{ {
const double f = 4294967296.0 * 4294967296.0; // 2**64 const double exp64 = 4294967296.0 * 4294967296.0; // 2**64
return ( ( u[3] * f + u[2] ) * f + u[1] ) * f + u[0]; return ( ( u[3] * exp64 + u[2] ) * exp64 + u[1] ) * exp64 + u[0];
} }
void work_set_target_ratio( struct work* work, uint32_t* hash ) void work_set_target_ratio( struct work* work, const void *hash )
{ {
double dhash; double dhash;
dhash = u256_to_double( (const uint64_t*)hash ); dhash = u256_to_double( (const uint64_t*)hash );
if ( dhash > 0. ) if ( likely( dhash > 0. ) )
work->sharediff = work->targetdiff * work->sharediff = work->targetdiff *
u256_to_double( (const uint64_t*)( work->target ) ) / dhash; u256_to_double( (const uint64_t*)( work->target ) ) / dhash;
else else
@@ -1833,38 +1842,38 @@ void work_set_target_ratio( struct work* work, uint32_t* hash )
pthread_mutex_unlock( &stats_lock ); pthread_mutex_unlock( &stats_lock );
} }
bool submit_solution( struct work *work, void *hash, bool submit_solution( struct work *work, const void *hash,
struct thr_info *thr ) const struct thr_info *thr )
{ {
if ( submit_work( thr, work ) ) if ( likely( submit_work( thr, work ) ) )
{ {
submitted_share_count++; submitted_share_count++;
work_set_target_ratio( work, hash ); work_set_target_ratio( work, hash );
if ( !opt_quiet ) if ( !opt_quiet )
applog( LOG_NOTICE, "%d: submitted by thread %d, job %s", applog( LOG_NOTICE, "%d submitted by thread %d, job %s",
submitted_share_count, thr->id, work->job_id ); submitted_share_count, thr->id, work->job_id );
return true; return true;
} }
else else
applog( LOG_WARNING, "%d: failed to submit share.", applog( LOG_WARNING, "%d failed to submit share.",
submitted_share_count ); submitted_share_count );
return false; return false;
} }
bool submit_lane_solution( struct work *work, void *hash, bool submit_lane_solution( struct work *work, const void *hash,
struct thr_info *thr, int lane ) const struct thr_info *thr, const int lane )
{ {
if ( submit_work( thr, work ) ) if ( likely( submit_work( thr, work ) ) )
{ {
submitted_share_count++; submitted_share_count++;
work_set_target_ratio( work, hash ); work_set_target_ratio( work, hash );
if ( !opt_quiet ) if ( !opt_quiet )
applog( LOG_NOTICE, "%d: submitted by thread %d, lane %d, job %s", applog( LOG_NOTICE, "%d submitted by thread %d, lane %d, job %s",
submitted_share_count, thr->id, lane, work->job_id ); submitted_share_count, thr->id, lane, work->job_id );
return true; return true;
} }
else else
applog( LOG_WARNING, "%d: failed to submit share.", applog( LOG_WARNING, "%d failed to submit share.",
submitted_share_count ); submitted_share_count );
return false; return false;
} }
@@ -1971,26 +1980,25 @@ double std_calc_network_diff( struct work* work )
return d; return d;
} }
uint32_t* std_get_nonceptr( uint32_t *work_data ) uint32_t *std_get_nonceptr( uint32_t *work_data )
{ {
return work_data + algo_gate.nonce_index; return work_data + algo_gate.nonce_index;
} }
uint32_t* jr2_get_nonceptr( uint32_t *work_data ) uint32_t *jr2_get_nonceptr( uint32_t *work_data )
{ {
// nonce is misaligned, use byte offset // nonce is misaligned, use byte offset
return (uint32_t*) ( ((uint8_t*) work_data) + algo_gate.nonce_index ); return (uint32_t*) ( ((uint8_t*) work_data) + algo_gate.nonce_index );
} }
void std_get_new_work( struct work* work, struct work* g_work, int thr_id, void std_get_new_work( struct work* work, struct work* g_work, int thr_id,
uint32_t *end_nonce_ptr, bool clean_job ) uint32_t *end_nonce_ptr, bool clean_job )
{ {
uint32_t *nonceptr = algo_gate.get_nonceptr( work->data ); uint32_t *nonceptr = algo_gate.get_nonceptr( work->data );
bool force_new_work = work->job_id ? strtoul( work->job_id, NULL, 16 ) bool force_new_work = work->job_id ? strtoul( work->job_id, NULL, 16 ) !=
!= strtoul( g_work->job_id, NULL, 16 ) strtoul( g_work->job_id, NULL, 16 )
: true; : true;
if ( force_new_work || *nonceptr >= *end_nonce_ptr if ( force_new_work || *nonceptr >= *end_nonce_ptr
|| ( memcmp( work->data, g_work->data, algo_gate.work_cmp_size ) || ( memcmp( work->data, g_work->data, algo_gate.work_cmp_size )
@@ -2016,7 +2024,7 @@ void jr2_get_new_work( struct work* work, struct work* g_work, int thr_id,
if ( memcmp( work->data, g_work->data, algo_gate.nonce_index ) if ( memcmp( work->data, g_work->data, algo_gate.nonce_index )
|| memcmp( ((uint8_t*) work->data) + JR2_WORK_CMP_INDEX_2, || memcmp( ((uint8_t*) work->data) + JR2_WORK_CMP_INDEX_2,
((uint8_t*) g_work->data) + JR2_WORK_CMP_INDEX_2, ((uint8_t*) g_work->data) + JR2_WORK_CMP_INDEX_2,
JR2_WORK_CMP_SIZE_2 ) ) JR2_WORK_CMP_SIZE_2 ) )
{ {
work_free( work ); work_free( work );
work_copy( work, g_work ); work_copy( work, g_work );
@@ -2065,39 +2073,30 @@ static void *miner_thread( void *userdata )
* error if it fails */ * error if it fails */
if (!opt_benchmark && opt_priority == 0) if (!opt_benchmark && opt_priority == 0)
{ {
setpriority(PRIO_PROCESS, 0, 19); setpriority(PRIO_PROCESS, 0, 19);
drop_policy(); drop_policy();
} }
else else
{ {
int prio = 0; int prio = 0;
#ifndef WIN32 #ifndef WIN32
prio = 18; prio = 18;
// note: different behavior on linux (-19 to 19) // note: different behavior on linux (-19 to 19)
switch (opt_priority) switch ( opt_priority )
{ {
case 1: case 1: prio = 5; break;
prio = 5; case 2: prio = 0; break;
break; case 3: prio = -5; break;
case 2: case 4: prio = -10; break;
prio = 0; case 5: prio = -15;
break; }
case 3: if (opt_debug)
prio = -5; applog(LOG_DEBUG, "Thread %d priority %d (nice %d)", thr_id,
break;
case 4:
prio = -10;
break;
case 5:
prio = -15;
}
if (opt_debug)
applog(LOG_DEBUG, "Thread %d priority %d (nice %d)", thr_id,
opt_priority, prio ); opt_priority, prio );
#endif #endif
setpriority(PRIO_PROCESS, 0, prio); setpriority(PRIO_PROCESS, 0, prio);
if (opt_priority == 0) if ( opt_priority == 0 )
drop_policy(); drop_policy();
} }
// CPU thread affinity // CPU thread affinity
if ( num_cpus > 1 ) if ( num_cpus > 1 )
@@ -2150,7 +2149,7 @@ static void *miner_thread( void *userdata )
} }
// wait for stratum to send first job // wait for stratum to send first job
if ( have_stratum ) while ( !g_work.job_id ) sleep(1); if ( have_stratum ) while ( unlikely( !g_work.job_id ) ) sleep(1);
while (1) while (1)
{ {
@@ -2159,7 +2158,7 @@ static void *miner_thread( void *userdata )
int64_t max64 = 1000; int64_t max64 = 1000;
int nonce_found = 0; int nonce_found = 0;
if ( algo_gate.do_this_thread( thr_id ) ) if ( likely( algo_gate.do_this_thread( thr_id ) ) )
{ {
if ( have_stratum ) if ( have_stratum )
{ {
@@ -2194,10 +2193,10 @@ static void *miner_thread( void *userdata )
} // do_this_thread } // do_this_thread
algo_gate.resync_threads( &work ); algo_gate.resync_threads( &work );
if ( !algo_gate.ready_to_mine( &work, &stratum, thr_id ) ) if ( unlikely( !algo_gate.ready_to_mine( &work, &stratum, thr_id ) ) )
continue; continue;
// conditional mining // conditional mining
if (!wanna_mine(thr_id)) if ( unlikely( !wanna_mine( thr_id ) ) )
{ {
sleep(5); sleep(5);
continue; continue;
@@ -2209,7 +2208,7 @@ static void *miner_thread( void *userdata )
max64 = g_work_time + ( have_longpoll ? LP_SCANTIME : opt_scantime ) max64 = g_work_time + ( have_longpoll ? LP_SCANTIME : opt_scantime )
- time(NULL); - time(NULL);
// time limit // time limit
if ( opt_time_limit && firstwork_time ) if ( unlikely( opt_time_limit && firstwork_time ) )
{ {
int passed = (int)( time(NULL) - firstwork_time ); int passed = (int)( time(NULL) - firstwork_time );
int remain = (int)( opt_time_limit - passed ); int remain = (int)( opt_time_limit - passed );
@@ -2267,7 +2266,7 @@ static void *miner_thread( void *userdata )
pthread_mutex_unlock( &stats_lock ); pthread_mutex_unlock( &stats_lock );
} }
// If unsubmiited nonce(s) found, submit now. // If unsubmiited nonce(s) found, submit now.
if ( nonce_found && !opt_benchmark ) if ( unlikely( nonce_found && !opt_benchmark ) )
{ {
applog( LOG_WARNING, "BUG: See RELEASE_NOTES for reporting bugs. Algo = %s.", applog( LOG_WARNING, "BUG: See RELEASE_NOTES for reporting bugs. Algo = %s.",
algo_names[ opt_algo ] ); algo_names[ opt_algo ] );
@@ -2292,7 +2291,7 @@ static void *miner_thread( void *userdata )
} }
} }
// display hashrate // display hashrate
if ( opt_hash_meter ) if ( unlikely( opt_hash_meter ) )
{ {
char hr[16]; char hr[16];
char hr_units[2] = {0,0}; char hr_units[2] = {0,0};
@@ -2310,8 +2309,8 @@ static void *miner_thread( void *userdata )
// Display benchmark total // Display benchmark total
// Update hashrate for API if no shares accepted yet. // Update hashrate for API if no shares accepted yet.
if ( ( opt_benchmark || !accepted_share_count ) if ( unlikely( ( opt_benchmark || !accepted_share_count )
&& thr_id == opt_n_threads - 1 ) && thr_id == opt_n_threads - 1 ) )
{ {
double hashrate = 0.; double hashrate = 0.;
for ( i = 0; i < opt_n_threads; i++ ) for ( i = 0; i < opt_n_threads; i++ )
@@ -2630,12 +2629,11 @@ void std_stratum_gen_work( struct stratum_ctx *sctx, struct work *g_work )
algo_gate.build_extraheader( g_work, sctx ); algo_gate.build_extraheader( g_work, sctx );
net_diff = algo_gate.calc_network_diff( g_work ); net_diff = algo_gate.calc_network_diff( g_work );
algo_gate.set_work_data_endian( g_work ); algo_gate.set_work_data_endian( g_work );
pthread_mutex_unlock( &sctx->work_lock );
work_set_target( g_work, sctx->job.diff work_set_target( g_work, sctx->job.diff
/ ( opt_target_factor * opt_diff_factor ) ); / ( opt_target_factor * opt_diff_factor ) );
pthread_mutex_unlock( &sctx->work_lock );
if ( opt_debug ) if ( opt_debug )
{ {
unsigned char *xnonce2str = abin2hex( g_work->xnonce2, unsigned char *xnonce2str = abin2hex( g_work->xnonce2,
@@ -2645,60 +2643,72 @@ void std_stratum_gen_work( struct stratum_ctx *sctx, struct work *g_work )
free( xnonce2str ); free( xnonce2str );
} }
// Log new block and/or stratum difficulty change. double hr = 0.;
pthread_mutex_lock( &stats_lock );
for ( int i = 0; i < opt_n_threads; i++ )
hr += thr_hashrates[i];
global_hashrate = hr;
pthread_mutex_unlock( &stats_lock );
if ( stratum_diff != sctx->job.diff )
applog( LOG_BLUE, "New stratum diff %g, block %d, job %s",
sctx->job.diff, sctx->block_height, g_work->job_id );
else if ( last_block_height != sctx->block_height )
applog( LOG_BLUE, "New block %d, job %s",
sctx->block_height, g_work->job_id );
else
applog( LOG_BLUE,"New job %s", g_work->job_id );
// Update data and calculate new estimates.
if ( ( stratum_diff != sctx->job.diff ) if ( ( stratum_diff != sctx->job.diff )
|| ( last_block_height != sctx->block_height ) ) || ( last_block_height != sctx->block_height ) )
{ {
double hr = 0.; static bool multipool = false;
new_job = false; if ( stratum.block_height < last_block_height ) multipool = true;
pthread_mutex_lock( &stats_lock ); if ( unlikely( !session_first_block ) )
session_first_block = stratum.block_height;
last_block_height = stratum.block_height;
stratum_diff = sctx->job.diff;
last_targetdiff = g_work->targetdiff;
for ( int i = 0; i < opt_n_threads; i++ ) if ( !opt_quiet )
hr += thr_hashrates[i]; {
global_hashrate = hr; applog2( LOG_INFO, "%s: %s", algo_names[opt_algo], short_url );
pthread_mutex_unlock( &stats_lock ); applog2( LOG_INFO, "Diff: Net %.3g, Stratum %.3g, Target %.3g",
net_diff, stratum_diff, last_targetdiff );
if ( likely( hr > 0. ) )
{
char hr_units[4] = {0};
char block_ttf[32];
char share_ttf[32];
if ( !opt_quiet ) sprintf_et( block_ttf, net_diff * diff_to_hash / hr );
{ sprintf_et( share_ttf, last_targetdiff * diff_to_hash / hr );
if ( stratum_diff != sctx->job.diff ) scale_hash_for_display ( &hr, hr_units );
applog( LOG_BLUE, "New stratum diff %g, block %d, job %s",
sctx->job.diff, sctx->block_height, g_work->job_id ); applog2( LOG_INFO, "TTF @ %.2f %sh/s: block %s, share %s",
else if ( last_block_height != sctx->block_height ) hr, hr_units, block_ttf, share_ttf );
applog( LOG_BLUE, "New block %d, job %s", sctx->block_height, if ( !multipool && net_diff > 0. )
g_work->job_id ); {
else struct timeval now, et;
applog( LOG_BLUE,"New job %s.", g_work->job_id ); gettimeofday( &now, NULL );
} timeval_subtract( &et, &now, &session_start );
double net_hr = net_diff * diff_to_hash;
char net_ttf[32];
char net_hr_units[4] = {0};
// Update data and calculate new estimates. sprintf_et( net_ttf,
stratum_diff = sctx->job.diff; ( last_block_height - session_first_block ) == 0 ? 0 :
last_block_height = stratum.block_height; et.tv_sec / ( last_block_height - session_first_block ) );
last_targetdiff = g_work->targetdiff;
if ( !opt_quiet ) scale_hash_for_display ( &net_hr, net_hr_units );
{
applog2( LOG_INFO, "%s %s block %d", short_url,
algo_names[opt_algo], stratum.block_height );
applog2( LOG_INFO, "Diff: net %g, stratum %g, target %g",
net_diff, stratum_diff, last_targetdiff );
}
if ( hr > 0. ) applog2( LOG_INFO, "TTF @ %.2f %sh/s: %s",
{ net_hr, net_hr_units, net_ttf );
char hr_units[4] = {0}; }
char block_ttf[32]; } // hr > 0
char share_ttf[32]; } // !quiet
sprintf_et( block_ttf, net_diff * diff_to_hash / hr );
sprintf_et( share_ttf, last_targetdiff * diff_to_hash / hr );
scale_hash_for_display ( &hr, hr_units );
if ( !opt_quiet )
{
applog2( LOG_INFO, "TTF @ %.2f %sh/s: block %s, share %s",
hr, hr_units, block_ttf, share_ttf );
}
}
} // new diff/block } // new diff/block
} }
@@ -2726,7 +2736,7 @@ static void *stratum_thread(void *userdata )
{ {
int failures = 0; int failures = 0;
if ( stratum_need_reset ) if ( unlikely( stratum_need_reset ) )
{ {
stratum_need_reset = false; stratum_need_reset = false;
stratum_disconnect( &stratum ); stratum_disconnect( &stratum );
@@ -2763,8 +2773,7 @@ static void *stratum_thread(void *userdata )
applog(LOG_ERR, "...retry after %d seconds", opt_fail_pause); applog(LOG_ERR, "...retry after %d seconds", opt_fail_pause);
sleep(opt_fail_pause); sleep(opt_fail_pause);
} }
if ( unlikely( jsonrpc_2 ) )
if (jsonrpc_2)
{ {
work_free(&g_work); work_free(&g_work);
work_copy(&g_work, &stratum.work); work_copy(&g_work, &stratum.work);
@@ -2777,28 +2786,12 @@ static void *stratum_thread(void *userdata )
if ( stratum.job.job_id if ( stratum.job.job_id
&& ( !g_work_time || strcmp( stratum.job.job_id, g_work.job_id ) ) ) && ( !g_work_time || strcmp( stratum.job.job_id, g_work.job_id ) ) )
{ {
new_job = true;
pthread_mutex_lock(&g_work_lock); pthread_mutex_lock(&g_work_lock);
algo_gate.stratum_gen_work( &stratum, &g_work ); algo_gate.stratum_gen_work( &stratum, &g_work );
time(&g_work_time); time(&g_work_time);
pthread_mutex_unlock(&g_work_lock); pthread_mutex_unlock(&g_work_lock);
restart_threads(); restart_threads();
}
if ( stratum.job.clean || jsonrpc_2 )
{
if ( !opt_quiet && last_block_height && new_job
&& ( last_block_height == stratum.block_height ) )
{
new_job = false;
applog( LOG_BLUE,"New job %s", g_work.job_id );
}
}
else if (opt_debug && !opt_quiet)
{
applog( LOG_BLUE, "%s asks job %d for block %d", short_url,
strtoul( stratum.job.job_id, NULL, 16 ), stratum.block_height );
}
} // stratum.job.job_id
if ( stratum_socket_full( &stratum, opt_timeout ) ) if ( stratum_socket_full( &stratum, opt_timeout ) )
{ {
@@ -3751,6 +3744,7 @@ int main(int argc, char *argv[])
applog(LOG_WARNING,"available on Linux. Using default affinity."); applog(LOG_WARNING,"available on Linux. Using default affinity.");
opt_affinity = -1; opt_affinity = -1;
} }
/*
else else
{ {
affine_to_cpu_mask( -1, opt_affinity ); affine_to_cpu_mask( -1, opt_affinity );
@@ -3769,6 +3763,7 @@ int main(int argc, char *argv[])
#endif #endif
} }
} }
*/
} }
#ifdef HAVE_SYSLOG_H #ifdef HAVE_SYSLOG_H
@@ -3800,7 +3795,7 @@ int main(int argc, char *argv[])
/* start work I/O thread */ /* start work I/O thread */
if (thread_create(thr, workio_thread)) if (thread_create(thr, workio_thread))
{ {
applog(LOG_ERR, "work thread create failed"); applog(LOG_ERR, "work thread create failed");
return 1; return 1;
} }
@@ -3866,7 +3861,7 @@ int main(int argc, char *argv[])
thr->q = tq_new(); thr->q = tq_new();
if (!thr->q) if (!thr->q)
return 1; return 1;
err = thread_create(thr, miner_thread); err = thread_create(thr, miner_thread);
if (err) { if (err) {
applog(LOG_ERR, "thread %d create failed", i); applog(LOG_ERR, "thread %d create failed", i);
return 1; return 1;

12
miner.h
View File

@@ -313,12 +313,14 @@ size_t address_to_script( unsigned char *out, size_t outsz, const char *addr );
int timeval_subtract( struct timeval *result, struct timeval *x, int timeval_subtract( struct timeval *result, struct timeval *x,
struct timeval *y); struct timeval *y);
bool fulltest( const uint32_t *hash, const uint32_t *target ); bool fulltest( const uint32_t *hash, const uint32_t *target );
bool valid_hash( const void*, const void* );
void work_set_target( struct work* work, double diff ); void work_set_target( struct work* work, double diff );
double target_to_diff( uint32_t* target ); double target_to_diff( uint32_t* target );
extern void diff_to_target(uint32_t *target, double diff); extern void diff_to_target(uint32_t *target, double diff);
double hash_target_ratio( uint32_t* hash, uint32_t* target ); double hash_target_ratio( uint32_t* hash, uint32_t* target );
void work_set_target_ratio( struct work* work, uint32_t* hash ); void work_set_target_ratio( struct work* work, const void *hash );
struct thr_info { struct thr_info {
int id; int id;
@@ -330,10 +332,10 @@ struct thr_info {
//struct thr_info *thr_info; //struct thr_info *thr_info;
bool submit_solution( struct work *work, void *hash, bool submit_solution( struct work *work, const void *hash,
struct thr_info *thr ); const struct thr_info *thr );
bool submit_lane_solution( struct work *work, void *hash, bool submit_lane_solution( struct work *work, const void *hash,
struct thr_info *thr, int lane ); const struct thr_info *thr, const int lane );
//bool submit_work( struct thr_info *thr, const struct work *work_in ); //bool submit_work( struct thr_info *thr, const struct work *work_in );

View File

@@ -46,10 +46,11 @@
#define HWMON_PATH \ #define HWMON_PATH \
"/sys/class/hwmon/hwmon2/temp1_input" "/sys/class/hwmon/hwmon2/temp1_input"
/* // need this for Ryzen
#define HWMON_ALT \ #define HWMON_ALT \
"/sys/class/hwmon/hwmon0/temp1_input" "/sys/class/hwmon/hwmon0/temp1_input"
/*
#define HWMON_ALT1 \ #define HWMON_ALT1 \
"/sys/devices/platform/coretemp.0/hwmon/hwmon1/temp1_input" "/sys/devices/platform/coretemp.0/hwmon/hwmon1/temp1_input"
*/ */
@@ -84,6 +85,9 @@ static inline float linux_cputemp(int core)
if (!fd) if (!fd)
fd = fopen(HWMON_PATH, "r"); fd = fopen(HWMON_PATH, "r");
if (!fd)
fd = fopen(HWMON_ALT, "r");
if (!fd) if (!fd)
return tc; return tc;

51
util.c
View File

@@ -982,40 +982,59 @@ int timeval_subtract(struct timeval *result, struct timeval *x,
return x->tv_sec < y->tv_sec; return x->tv_sec < y->tv_sec;
} }
bool fulltest(const uint32_t *hash, const uint32_t *target) // Use this when deinterleaved
// do 64 bit test 4 iterations
inline bool valid_hash( const void *hash, const void *target )
{
const uint64_t *h = (const uint64_t*)hash;
const uint64_t *t = (const uint64_t*)target;
if ( h[3] > t[3] ) return false;
if ( h[3] < t[3] ) return true;
if ( h[2] > t[2] ) return false;
if ( h[2] < t[2] ) return true;
if ( h[1] > t[1] ) return false;
if ( h[1] < t[1] ) return true;
if ( h[0] > t[0] ) return false;
return true;
}
bool fulltest( const uint32_t *hash, const uint32_t *target )
{ {
int i; int i;
bool rc = true; bool rc = true;
for (i = 7; i >= 0; i--) { for ( i = 7; i >= 0; i-- )
if (hash[i] > target[i]) { {
if ( hash[i] > target[i] )
{
rc = false; rc = false;
break; break;
} }
if (hash[i] < target[i]) { if ( hash[i] < target[i] )
{
rc = true; rc = true;
break; break;
} }
} }
if (opt_debug) { if ( opt_debug )
{
uint32_t hash_be[8], target_be[8]; uint32_t hash_be[8], target_be[8];
char hash_str[65], target_str[65]; char hash_str[65], target_str[65];
for (i = 0; i < 8; i++) { for ( i = 0; i < 8; i++ )
be32enc(hash_be + i, hash[7 - i]); {
be32enc(target_be + i, target[7 - i]); be32enc( hash_be + i, hash[7 - i] );
be32enc( target_be + i, target[7 - i] );
} }
bin2hex(hash_str, (unsigned char *)hash_be, 32); bin2hex( hash_str, (unsigned char *)hash_be, 32 );
bin2hex(target_str, (unsigned char *)target_be, 32); bin2hex( target_str, (unsigned char *)target_be, 32 );
applog(LOG_DEBUG, "DEBUG: %s\nHash: %s\nTarget: %s", applog( LOG_DEBUG, "DEBUG: %s\nHash: %s\nTarget: %s",
rc ? "hash <= target" rc ? "hash <= target"
: "hash > target (false positive)", : "hash > target (false positive)",
hash_str, hash_str, target_str );
target_str);
} }
return rc; return rc;
} }