Compare commits

..

3 Commits

Author SHA1 Message Date
Jay D Dee
cdd587537e v3.14.3 2020-06-18 17:30:26 -04:00
Jay D Dee
51a1d91abd v3.14.2 2020-05-30 21:20:44 -04:00
Jay D Dee
13563e2598 v3.14.1 2020-05-21 13:00:29 -04:00
27 changed files with 638 additions and 698 deletions

View File

@@ -65,6 +65,31 @@ If not what makes it happen or not happen?
Change Log
----------
v3.14.3
#265: more mutex changes to reduce blocking with high thread count.
#267: fixed hodl algo potential memory alignment issue,
add warning when thread count is not valid for mining hodl algo.
v3.14.2
The second line of the Share Accepted log is no longer displayed,
new Xnonce log is added and other small log tweaks.
#265: Cleanup use of mutex.
v3.14.1
GBT and getwork log changes:
fixed missing TTF in New Block log,
ntime no longer byte-swapped for display in New Work log,
fixed zero effective hash rate in Periodic Report log,
deleted "Current block is..." log.
Renamed stratum "New Job" log to "New Work" to be consistent with the solo
version of the log. Added more data to both versions.
v3.14.0
Changes to solo mining:

View File

@@ -128,6 +128,119 @@ int scanhash_generic( struct work *work, uint32_t max_nonce,
return 0;
}
#if defined(__AVX2__)
//int scanhash_4way_64_64( struct work *work, uint32_t max_nonce,
// uint64_t *hashes_done, struct thr_info *mythr )
//int scanhash_4way_64_640( struct work *work, uint32_t max_nonce,
// uint64_t *hashes_done, struct thr_info *mythr )
int scanhash_4way_64in_32out( struct work *work, uint32_t max_nonce,
uint64_t *hashes_done, struct thr_info *mythr )
{
uint32_t hash32[8*4] __attribute__ ((aligned (64)));
uint32_t vdata[20*4] __attribute__ ((aligned (64)));
uint32_t lane_hash[8] __attribute__ ((aligned (64)));
uint32_t *hash32_d7 = &(hash32[ 7*4 ]);
uint32_t *pdata = work->data;
const uint32_t *ptarget = work->target;
const uint32_t first_nonce = pdata[19];
const uint32_t last_nonce = max_nonce - 4;
__m256i *noncev = (__m256i*)vdata + 9;
uint32_t n = first_nonce;
const int thr_id = mythr->id;
const uint32_t targ32_d7 = ptarget[7];
const bool bench = opt_benchmark;
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
{
if ( likely( algo_gate.hash( hash32, vdata, thr_id ) ) )
for ( int lane = 0; lane < 4; lane++ )
if ( unlikely( hash32_d7[ lane ] <= targ32_d7 && !bench ) )
{
extr_lane_4x32( lane_hash, hash32, lane, 256 );
if ( valid_hash( lane_hash, ptarget ) )
{
pdata[19] = bswap_32( n + lane );
submit_solution( work, lane_hash, mythr );
}
}
*noncev = _mm256_add_epi32( *noncev,
m256_const1_64( 0x0000000400000000 ) );
n += 4;
} while ( likely( ( n <= last_nonce ) && !work_restart[thr_id].restart ) );
pdata[19] = n;
*hashes_done = n - first_nonce;
return 0;
}
//int scanhash_8way_32_32( struct work *work, uint32_t max_nonce,
// uint64_t *hashes_done, struct thr_info *mythr )
#endif
#if defined(__AVX512F__) && defined(__AVX512VL__) && defined(__AVX512DQ__) && defined(__AVX512BW__)
//int scanhash_8way_64_64( struct work *work, uint32_t max_nonce,
// uint64_t *hashes_done, struct thr_info *mythr )
//int scanhash_8way_64_640( struct work *work, uint32_t max_nonce,
// uint64_t *hashes_done, struct thr_info *mythr )
int scanhash_8way_64in_32out( struct work *work, uint32_t max_nonce,
uint64_t *hashes_done, struct thr_info *mythr )
{
uint32_t hash32[8*8] __attribute__ ((aligned (128)));
uint32_t vdata[20*8] __attribute__ ((aligned (64)));
uint32_t lane_hash[8] __attribute__ ((aligned (64)));
uint32_t *hash32_d7 = &(hash32[7*8]);
uint32_t *pdata = work->data;
const uint32_t *ptarget = work->target;
const uint32_t first_nonce = pdata[19];
const uint32_t last_nonce = max_nonce - 8;
__m512i *noncev = (__m512i*)vdata + 9;
uint32_t n = first_nonce;
const int thr_id = mythr->id;
const uint32_t targ32_d7 = ptarget[7];
const bool bench = opt_benchmark;
mm512_bswap32_intrlv80_8x64( vdata, pdata );
*noncev = mm512_intrlv_blend_32(
_mm512_set_epi32( n+7, 0, n+6, 0, n+5, 0, n+4, 0,
n+3, 0, n+2, 0, n+1, 0, n, 0 ), *noncev );
do
{
if ( likely( algo_gate.hash( hash32, vdata, thr_id ) ) )
for ( int lane = 0; lane < 8; lane++ )
if ( unlikely( ( hash32_d7[ lane ] <= targ32_d7 ) && !bench ) )
{
extr_lane_8x32( lane_hash, hash32, lane, 256 );
if ( likely( valid_hash( lane_hash, ptarget ) ) )
{
pdata[19] = bswap_32( n + lane );
submit_solution( work, lane_hash, mythr );
}
}
*noncev = _mm512_add_epi32( *noncev,
m512_const1_64( 0x0000000800000000 ) );
n += 8;
} while ( likely( ( n < last_nonce ) && !work_restart[thr_id].restart ) );
pdata[19] = n;
*hashes_done = n - first_nonce;
return 0;
}
//int scanhash_16way_32_32( struct work *work, uint32_t max_nonce,
// uint64_t *hashes_done, struct thr_info *mythr )
#endif
int null_hash()
{
applog(LOG_WARNING,"SWERR: null_hash unsafe null function");

View File

@@ -110,12 +110,12 @@ inline bool set_excl ( set_t a, set_t b ) { return (a & b) == 0; }
typedef struct
{
// Mandatory functions, one of these is mandatory. If the default scanhash
// Mandatory functions, one of these is mandatory. If a generic scanhash
// is used a custom hash function must be registered, with a custom scanhash
// the hash function is not necessary.
// the custom hash function can be called directly and doesn't need to be
// registered in the gate.
int ( *scanhash ) ( struct work*, uint32_t, uint64_t*, struct thr_info* );
//int ( *hash ) ( void*, const void*, uint32_t ) ;
int ( *hash ) ( void*, const void*, int );
//optional, safe to use default in most cases
@@ -128,7 +128,7 @@ bool ( *miner_thread_init ) ( int );
void ( *get_new_work ) ( struct work*, struct work*, int, uint32_t* );
// Decode getwork blockheader
bool ( *work_decode ) ( const json_t*, struct work* );
bool ( *work_decode ) ( struct work* );
// Extra getwork data
void ( *decode_extra_data ) ( struct work*, uint64_t* );
@@ -203,19 +203,61 @@ void four_way_not_tested();
#define STD_WORK_DATA_SIZE 128
#define STD_WORK_CMP_SIZE 76
#define JR2_NONCE_INDEX 39 // 8 bit offset
//#define JR2_NONCE_INDEX 39 // 8 bit offset
// These indexes are only used with JSON RPC2 and are not gated.
#define JR2_WORK_CMP_INDEX_2 43
#define JR2_WORK_CMP_SIZE_2 33
//#define JR2_WORK_CMP_INDEX_2 43
//#define JR2_WORK_CMP_SIZE_2 33
// deprecated, use generic instead
int null_scanhash();
// Default generic, may be used in many cases.
// N-way is more complicated, requires many different implementations
// depending on architecture, input format, and output format.
// Naming convention is scanhash_[N]way_[input format]in_[output format]out
// N = number of lanes
// input/output format:
// 32: 32 bit interleaved parallel lanes
// 64: 64 bit interleaved parallel lanes
// 640: input only, not interleaved, contiguous serial 640 bit lanes.
// 256: output only, not interleaved, contiguous serial 256 bit lanes.
int scanhash_generic( struct work *work, uint32_t max_nonce,
uint64_t *hashes_done, struct thr_info *mythr );
#if defined(__AVX2__)
//int scanhash_4way_64in_64out( struct work *work, uint32_t max_nonce,
// uint64_t *hashes_done, struct thr_info *mythr );
//int scanhash_4way_64in_256out( struct work *work, uint32_t max_nonce,
// uint64_t *hashes_done, struct thr_info *mythr );
int scanhash_4way_64in_32out( struct work *work, uint32_t max_nonce,
uint64_t *hashes_done, struct thr_info *mythr );
//int scanhash_8way_32in_32out( struct work *work, uint32_t max_nonce,
// uint64_t *hashes_done, struct thr_info *mythr );
#endif
#if defined(__AVX512F__) && defined(__AVX512VL__) && defined(__AVX512DQ__) && defined(__AVX512BW__)
//int scanhash_8way_64in_64out( struct work *work, uint32_t max_nonce,
// uint64_t *hashes_done, struct thr_info *mythr );
//int scanhash_8way_64in_256out( struct work *work, uint32_t max_nonce,
// uint64_t *hashes_done, struct thr_info *mythr );
int scanhash_8way_64in_32out( struct work *work, uint32_t max_nonce,
uint64_t *hashes_done, struct thr_info *mythr );
//int scanhash_16way_32in_32out( struct work *work, uint32_t max_nonce,
// uint64_t *hashes_done, struct thr_info *mythr );
#endif
// displays warning
int null_hash ();
@@ -227,8 +269,8 @@ void std_get_new_work( struct work *work, struct work *g_work, int thr_id,
void sha256d_gen_merkle_root( char *merkle_root, struct stratum_ctx *sctx );
void SHA256_gen_merkle_root ( char *merkle_root, struct stratum_ctx *sctx );
bool std_le_work_decode( const json_t *val, struct work *work );
bool std_be_work_decode( const json_t *val, struct work *work );
bool std_le_work_decode( struct work *work );
bool std_be_work_decode( struct work *work );
bool std_le_submit_getwork_result( CURL *curl, struct work *work );
bool std_be_submit_getwork_result( CURL *curl, struct work *work );

View File

@@ -78,7 +78,6 @@ void decred_build_extraheader( struct work* g_work, struct stratum_ctx* sctx )
uint32_t extraheader[32] = { 0 };
int headersize = 0;
uint32_t* extradata = (uint32_t*) sctx->xnonce1;
size_t t;
int i;
// getwork over stratum, getwork merkle + header passed in coinb1
@@ -87,9 +86,6 @@ void decred_build_extraheader( struct work* g_work, struct stratum_ctx* sctx )
sizeof(extraheader) );
memcpy( extraheader, &sctx->job.coinbase[32], headersize );
// Increment extranonce2
for ( t = 0; t < sctx->xnonce2_size && !( ++sctx->job.xnonce2[t] ); t++ );
// Assemble block header
memset( g_work->data, 0, sizeof(g_work->data) );
g_work->data[0] = le32dec( sctx->job.version );

View File

@@ -99,9 +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 );
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 );
}
json_t *hodl_longpoll_rpc_call( CURL *curl, int *err, char* lp_url )
@@ -155,11 +159,10 @@ bool register_hodl_algo( algo_gate_t* gate )
applog( LOG_ERR, "Only CPUs with AES are supported, use legacy version.");
return false;
#endif
// if ( TOTAL_CHUNKS % opt_n_threads )
// {
// applog(LOG_ERR,"Thread count must be power of 2.");
// return false;
// }
if ( GARBAGE_SIZE % opt_n_threads )
applog( LOG_WARNING,"WARNING: Thread count must be power of 2. Miner may crash or produce invalid hash!" );
pthread_barrier_init( &hodl_barrier, NULL, opt_n_threads );
gate->optimizations = SSE42_OPT | AES_OPT | AVX2_OPT;
gate->scanhash = (void*)&hodl_scanhash;
@@ -171,7 +174,7 @@ bool register_hodl_algo( algo_gate_t* gate )
gate->resync_threads = (void*)&hodl_resync_threads;
gate->do_this_thread = (void*)&hodl_do_this_thread;
gate->work_cmp_size = 76;
hodl_scratchbuf = (unsigned char*)malloc( 1 << 30 );
hodl_scratchbuf = (unsigned char*)_mm_malloc( 1 << 30, 64 );
allow_getwork = false;
opt_target_factor = 8388608.0;
return ( hodl_scratchbuf != NULL );

View File

@@ -70,7 +70,7 @@ int scanhash_hodl_wolf( struct work* work, uint32_t max_nonce,
uint32_t *ptarget = work->target;
int threadNumber = mythr->id;
CacheEntry *Garbage = (CacheEntry*)hodl_scratchbuf;
CacheEntry Cache[AES_PARALLEL_N];
CacheEntry Cache[AES_PARALLEL_N] __attribute__ ((aligned (64)));
__m128i* data[AES_PARALLEL_N];
const __m128i* next[AES_PARALLEL_N];
uint32_t CollisionCount = 0;

View File

@@ -215,9 +215,6 @@ void phi2_build_extraheader( struct work* g_work, struct stratum_ctx* sctx )
size_t t;
algo_gate.gen_merkle_root( merkle_tree, sctx );
// Increment extranonce2
for ( t = 0; t < sctx->xnonce2_size && !( ++sctx->job.xnonce2[t] ); t++ );
// Assemble block header
algo_gate.build_block_header( g_work, le32dec( sctx->job.version ),
(uint32_t*) sctx->job.prevhash, (uint32_t*) merkle_tree,
le32dec( sctx->job.ntime ), le32dec(sctx->job.nbits), NULL );
@@ -225,7 +222,6 @@ void phi2_build_extraheader( struct work* g_work, struct stratum_ctx* sctx )
g_work->data[ 20+t ] = ((uint32_t*)sctx->job.extra)[t];
}
bool register_phi2_algo( algo_gate_t* gate )
{
gate->optimizations = SSE2_OPT | AES_OPT | AVX2_OPT | AVX512_OPT | VAES_OPT;

View File

@@ -156,6 +156,8 @@ 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 );
// ignore POK in first word
const int wkcmp_sz = 72; // (19-1) * sizeof(uint32_t)
uint32_t *nonceptr = work->data + algo_gate.nonce_index;
@@ -171,6 +173,8 @@ void zr5_get_new_work( struct work* work, struct work* g_work, int thr_id,
}
else
++(*nonceptr);
pthread_rwlock_unlock( &g_work_lock );
}
void zr5_display_pok( struct work* work )

View File

@@ -69,13 +69,9 @@ void lbry_build_block_header( struct work* g_work, uint32_t version,
void lbry_build_extraheader( struct work* g_work, struct stratum_ctx* sctx )
{
unsigned char merkle_root[64] = { 0 };
size_t t;
int i;
algo_gate.gen_merkle_root( merkle_root, sctx );
// Increment extranonce2
for ( t = 0; t < sctx->xnonce2_size && !( ++sctx->job.xnonce2[t] ); t++ );
// Assemble block header
memset( g_work->data, 0, sizeof(g_work->data) );
g_work->data[0] = le32dec( sctx->job.version );

View File

@@ -227,7 +227,7 @@ bool initialize_torture_garden()
}
// Produce a 32-byte hash from 80-byte input data
int minotaur_hash( void *output, const void *input )
int minotaur_hash( void *output, const void *input, int thr_id )
{
unsigned char hash[64] __attribute__ ((aligned (64)));

View File

@@ -135,18 +135,16 @@ void x16rt_getAlgoString( const uint32_t *timeHash, char *output)
void veil_build_extraheader( struct work* g_work, struct stratum_ctx* sctx )
{
uint32_t merkleroothash[8];
uint32_t witmerkleroothash[8];
uint32_t denom10[8];
uint32_t denom100[8];
uint32_t denom1000[8];
uint32_t denom10000[8];
int i;
uchar merkle_tree[64] = { 0 };
size_t t;
algo_gate.gen_merkle_root( merkle_tree, sctx );
// Increment extranonce2
for ( t = 0; t < sctx->xnonce2_size && !( ++sctx->job.xnonce2[t] ); t++ );
// Assemble block header
// algo_gate.build_block_header( g_work, le32dec( sctx->job.version ),
// (uint32_t*) sctx->job.prevhash, (uint32_t*) merkle_tree,
// le32dec( sctx->job.ntime ), le32dec(sctx->job.nbits) );
int i;
memset( g_work->data, 0, sizeof(g_work->data) );
g_work->data[0] = le32dec( sctx->job.version );
@@ -164,35 +162,35 @@ void veil_build_extraheader( struct work* g_work, struct stratum_ctx* sctx )
g_work->data[31] = 0x00000280;
for ( i = 0; i < 8; i++ )
g_work->merkleroothash[7 - i] = be32dec((uint32_t *)merkle_tree + i);
merkleroothash[7 - i] = be32dec((uint32_t *)merkle_tree + i);
for ( i = 0; i < 8; i++ )
g_work->witmerkleroothash[7 - i] = be32dec((uint32_t *)merkle_tree + i);
witmerkleroothash[7 - i] = be32dec((uint32_t *)merkle_tree + i);
for ( i = 0; i < 8; i++ )
g_work->denom10[i] = le32dec((uint32_t *)sctx->job.denom10 + i);
denom10[i] = le32dec((uint32_t *)sctx->job.denom10 + i);
for ( i = 0; i < 8; i++ )
g_work->denom100[i] = le32dec((uint32_t *)sctx->job.denom100 + i);
denom100[i] = le32dec((uint32_t *)sctx->job.denom100 + i);
for ( i = 0; i < 8; i++ )
g_work->denom1000[i] = le32dec((uint32_t *)sctx->job.denom1000 + i);
denom1000[i] = le32dec((uint32_t *)sctx->job.denom1000 + i);
for ( i = 0; i < 8; i++ )
g_work->denom10000[i] = le32dec((uint32_t *)sctx->job.denom10000 + i);
denom10000[i] = le32dec((uint32_t *)sctx->job.denom10000 + i);
uint32_t pofnhash[8];
memset(pofnhash, 0x00, 32);
char denom10_str [ 2 * sizeof( g_work->denom10 ) + 1 ];
char denom100_str [ 2 * sizeof( g_work->denom100 ) + 1 ];
char denom1000_str [ 2 * sizeof( g_work->denom1000 ) + 1 ];
char denom10000_str [ 2 * sizeof( g_work->denom10000 ) + 1 ];
char merkleroot_str [ 2 * sizeof( g_work->merkleroothash ) + 1 ];
char witmerkleroot_str[ 2 * sizeof( g_work->witmerkleroothash ) + 1 ];
char denom10_str [ 2 * sizeof( denom10 ) + 1 ];
char denom100_str [ 2 * sizeof( denom100 ) + 1 ];
char denom1000_str [ 2 * sizeof( denom1000 ) + 1 ];
char denom10000_str [ 2 * sizeof( denom10000 ) + 1 ];
char merkleroot_str [ 2 * sizeof( merkleroothash ) + 1 ];
char witmerkleroot_str[ 2 * sizeof( witmerkleroothash ) + 1 ];
char pofn_str [ 2 * sizeof( pofnhash ) + 1 ];
cbin2hex( denom10_str, (char*) g_work->denom10, 32 );
cbin2hex( denom100_str, (char*) g_work->denom100, 32 );
cbin2hex( denom1000_str, (char*) g_work->denom1000, 32 );
cbin2hex( denom10000_str, (char*) g_work->denom10000, 32 );
cbin2hex( merkleroot_str, (char*) g_work->merkleroothash, 32 );
cbin2hex( witmerkleroot_str, (char*) g_work->witmerkleroothash, 32 );
cbin2hex( denom10_str, (char*) denom10, 32 );
cbin2hex( denom100_str, (char*) denom100, 32 );
cbin2hex( denom1000_str, (char*) denom1000, 32 );
cbin2hex( denom10000_str, (char*) denom10000, 32 );
cbin2hex( merkleroot_str, (char*) merkleroothash, 32 );
cbin2hex( witmerkleroot_str, (char*) witmerkleroothash, 32 );
cbin2hex( pofn_str, (char*) pofnhash, 32 );
if ( true )

View File

@@ -58,7 +58,7 @@ union _sonoa_8way_context_overlay
typedef union _sonoa_8way_context_overlay sonoa_8way_context_overlay;
int sonoa_8way_hash( void *state, const void *input, int thrid )
int sonoa_8way_hash( void *state, const void *input, int thr_id )
{
uint64_t vhash[8*8] __attribute__ ((aligned (128)));
uint64_t vhashA[8*8] __attribute__ ((aligned (64)));
@@ -186,7 +186,7 @@ int sonoa_8way_hash( void *state, const void *input, int thrid )
#endif
if ( work_restart[thrid].restart ) return 0;
if ( work_restart[thr_id].restart ) return 0;
// 2
bmw512_8way_full( &ctx.bmw, vhash, vhash, 64 );
@@ -302,7 +302,7 @@ int sonoa_8way_hash( void *state, const void *input, int thrid )
hamsi512_8way_update( &ctx.hamsi, vhash, 64 );
hamsi512_8way_close( &ctx.hamsi, vhash );
if ( work_restart[thrid].restart ) return 0;
if ( work_restart[thr_id].restart ) return 0;
// 3
bmw512_8way_full( &ctx.bmw, vhash, vhash, 64 );
@@ -432,7 +432,7 @@ int sonoa_8way_hash( void *state, const void *input, int thrid )
sph_fugue512_full( &ctx.fugue, hash6, hash6, 64 );
sph_fugue512_full( &ctx.fugue, hash7, hash7, 64 );
if ( work_restart[thrid].restart ) return 0;
if ( work_restart[thr_id].restart ) return 0;
// 4
intrlv_8x64_512( vhash, hash0, hash1, hash2, hash3, hash4, hash5, hash6,
@@ -630,7 +630,7 @@ int sonoa_8way_hash( void *state, const void *input, int thrid )
#endif
if ( work_restart[thrid].restart ) return 0;
if ( work_restart[thr_id].restart ) return 0;
// 5
bmw512_8way_full( &ctx.bmw, vhash, vhash, 64 );
@@ -783,7 +783,7 @@ int sonoa_8way_hash( void *state, const void *input, int thrid )
sph_whirlpool512_full( &ctx.whirlpool, hash6, hash6, 64 );
sph_whirlpool512_full( &ctx.whirlpool, hash7, hash7, 64 );
if ( work_restart[thrid].restart ) return 0;
if ( work_restart[thr_id].restart ) return 0;
// 6
intrlv_8x64_512( vhash, hash0, hash1, hash2, hash3, hash4, hash5, hash6,
@@ -952,7 +952,7 @@ int sonoa_8way_hash( void *state, const void *input, int thrid )
sph_whirlpool512_full( &ctx.whirlpool, hash6, hash6, 64 );
sph_whirlpool512_full( &ctx.whirlpool, hash7, hash7, 64 );
if ( work_restart[thrid].restart ) return 0;
if ( work_restart[thr_id].restart ) return 0;
// 7
intrlv_8x64_512( vhash, hash0, hash1, hash2, hash3, hash4, hash5, hash6,
@@ -1118,49 +1118,6 @@ int sonoa_8way_hash( void *state, const void *input, int thrid )
return 1;
}
int scanhash_sonoa_8way( struct work *work, uint32_t max_nonce,
uint64_t *hashes_done, struct thr_info *mythr )
{
uint32_t hash[8*16] __attribute__ ((aligned (128)));
uint32_t vdata[20*8] __attribute__ ((aligned (64)));
uint32_t lane_hash[8] __attribute__ ((aligned (64)));
uint32_t *hashd7 = &(hash[7<<3]);
uint32_t *pdata = work->data;
const uint32_t *ptarget = work->target;
const uint32_t first_nonce = pdata[19];
const uint32_t last_nonce = max_nonce - 8;
__m512i *noncev = (__m512i*)vdata + 9; // aligned
uint32_t n = first_nonce;
const int thr_id = mythr->id;
const uint32_t targ32 = ptarget[7];
mm512_bswap32_intrlv80_8x64( vdata, pdata );
*noncev = mm512_intrlv_blend_32(
_mm512_set_epi32( n+7, 0, n+6, 0, n+5, 0, n+4, 0,
n+3, 0, n+2, 0, n+1, 0, n, 0 ), *noncev );
do
{
if ( sonoa_8way_hash( hash, vdata, thr_id ) )
for ( int lane = 0; lane < 8; lane++ )
if unlikely( ( hashd7[ lane ] <= targ32 ) )
{
extr_lane_8x32( lane_hash, hash, lane, 256 );
if ( likely( valid_hash( lane_hash, ptarget ) && !opt_benchmark ) )
{
pdata[19] = bswap_32( n + lane );
submit_solution( work, lane_hash, mythr );
}
}
*noncev = _mm512_add_epi32( *noncev,
m512_const1_64( 0x0000000800000000 ) );
n += 8;
} while ( likely( ( n < last_nonce ) && !work_restart[thr_id].restart ) );
pdata[19] = n;
*hashes_done = n - first_nonce;
return 0;
}
#elif defined(SONOA_4WAY)
union _sonoa_4way_context_overlay
@@ -1186,7 +1143,7 @@ union _sonoa_4way_context_overlay
typedef union _sonoa_4way_context_overlay sonoa_4way_context_overlay;
int sonoa_4way_hash( void *state, const void *input, int thrid )
int sonoa_4way_hash( void *state, const void *input, int thr_id )
{
uint64_t hash0[8] __attribute__ ((aligned (64)));
uint64_t hash1[8] __attribute__ ((aligned (64)));
@@ -1250,7 +1207,7 @@ int sonoa_4way_hash( void *state, const void *input, int thrid )
echo_full( &ctx.echo, (BitSequence *)hash3, 512,
(const BitSequence *)hash3, 64 );
if ( work_restart[thrid].restart ) return 0;
if ( work_restart[thr_id].restart ) return 0;
// 2
intrlv_4x64_512( vhash, hash0, hash1, hash2, hash3 );
@@ -1310,7 +1267,7 @@ int sonoa_4way_hash( void *state, const void *input, int thrid )
hamsi512_4way_update( &ctx.hamsi, vhash, 64 );
hamsi512_4way_close( &ctx.hamsi, vhash );
if ( work_restart[thrid].restart ) return 0;
if ( work_restart[thr_id].restart ) return 0;
// 3
bmw512_4way_init( &ctx.bmw );
@@ -1375,7 +1332,7 @@ int sonoa_4way_hash( void *state, const void *input, int thrid )
sph_fugue512_full( &ctx.fugue, hash2, hash2, 64 );
sph_fugue512_full( &ctx.fugue, hash3, hash3, 64 );
if ( work_restart[thrid].restart ) return 0;
if ( work_restart[thr_id].restart ) return 0;
// 4
intrlv_4x64_512( vhash, hash0, hash1, hash2, hash3 );
@@ -1472,7 +1429,7 @@ int sonoa_4way_hash( void *state, const void *input, int thrid )
shavite512_2way_init( &ctx.shavite );
shavite512_2way_update_close( &ctx.shavite, vhashB, vhashB, 64 );
if ( work_restart[thrid].restart ) return 0;
if ( work_restart[thr_id].restart ) return 0;
// 5
rintrlv_2x128_4x64( vhash, vhashA, vhashB, 512 );
@@ -1557,7 +1514,7 @@ int sonoa_4way_hash( void *state, const void *input, int thrid )
sph_whirlpool512_full( &ctx.whirlpool, hash2, hash2, 64 );
sph_whirlpool512_full( &ctx.whirlpool, hash3, hash3, 64 );
if ( work_restart[thrid].restart ) return 0;
if ( work_restart[thr_id].restart ) return 0;
// 6
intrlv_4x64_512( vhash, hash0, hash1, hash2, hash3 );
@@ -1650,7 +1607,7 @@ int sonoa_4way_hash( void *state, const void *input, int thrid )
sph_whirlpool512_full( &ctx.whirlpool, hash2, hash2, 64 );
sph_whirlpool512_full( &ctx.whirlpool, hash3, hash3, 64 );
if ( work_restart[thrid].restart ) return 0;
if ( work_restart[thr_id].restart ) return 0;
// 7
intrlv_4x64_512( vhash, hash0, hash1, hash2, hash3 );
@@ -1745,46 +1702,4 @@ int sonoa_4way_hash( void *state, const void *input, int thrid )
return 1;
}
int scanhash_sonoa_4way( struct work *work, const uint32_t max_nonce,
uint64_t *hashes_done, struct thr_info *mythr )
{
uint32_t hash[4*16] __attribute__ ((aligned (64)));
uint32_t vdata[24*4] __attribute__ ((aligned (64)));
uint32_t lane_hash[8] __attribute__ ((aligned (32)));
uint32_t *hashd7 = &( hash[7<<2] );
uint32_t *pdata = work->data;
const uint32_t *ptarget = work->target;
const uint32_t first_nonce = pdata[19];
const uint32_t last_nonce = max_nonce - 4;
const uint32_t targ32 = ptarget[7];
uint32_t n = first_nonce;
__m256i *noncev = (__m256i*)vdata + 9;
const int thr_id = mythr->id;
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
{
if ( sonoa_4way_hash( hash, vdata, thr_id ) )
for ( int lane = 0; lane < 4; lane++ )
if ( unlikely( hashd7[ lane ] <= targ32 ) )
{
extr_lane_4x32( lane_hash, hash, lane, 256 );
if ( likely( valid_hash( lane_hash, ptarget ) && !opt_benchmark ) )
{
pdata[19] = bswap_32( n + lane );
submit_solution( work, lane_hash, mythr );
}
}
*noncev = _mm256_add_epi32( *noncev,
m256_const1_64( 0x0000000400000000 ) );
n += 4;
} while ( likely( ( n < last_nonce ) && !work_restart[thr_id].restart ) );
pdata[19] = n;
*hashes_done = n - first_nonce;
return 0;
}
#endif

View File

@@ -3,14 +3,13 @@
bool register_sonoa_algo( algo_gate_t* gate )
{
#if defined (SONOA_8WAY)
gate->scanhash = (void*)&scanhash_sonoa_8way;
gate->scanhash = (void*)&scanhash_8way_64in_32out;
gate->hash = (void*)&sonoa_8way_hash;
#elif defined (SONOA_4WAY)
gate->scanhash = (void*)&scanhash_sonoa_4way;
gate->scanhash = (void*)&scanhash_4way_64in_32out;
gate->hash = (void*)&sonoa_4way_hash;
#else
init_sonoa_ctx();
// gate->scanhash = (void*)&scanhash_sonoa;
gate->hash = (void*)&sonoa_hash;
#endif
gate->optimizations = SSE2_OPT | AES_OPT | AVX2_OPT | AVX512_OPT | VAES_OPT;

View File

@@ -14,21 +14,15 @@ bool register_sonoa_algo( algo_gate_t* gate );
#if defined(SONOA_8WAY)
int sonoa_8way_hash( void *state, const void *input, int thrid );
int scanhash_sonoa_8way( struct work *work, uint32_t max_nonce,
uint64_t *hashes_done, struct thr_info *mythr );
int sonoa_8way_hash( void *state, const void *input, int thr_id );
#elif defined(SONOA_4WAY)
int sonoa_4way_hash( void *state, const void *input, int thrid );
int scanhash_sonoa_4way( struct work *work, uint32_t max_nonce,
uint64_t *hashes_done, struct thr_info *mythr );
int sonoa_4way_hash( void *state, const void *input, int thr_id );
#else
int sonoa_hash( void *state, const void *input, int thrid );
int scanhash_sonoa( struct work *work, uint32_t max_nonce,
uint64_t *hashes_done, struct thr_info *mythr );
int sonoa_hash( void *state, const void *input, int thr_id );
void init_sonoa_ctx();
#endif

View File

@@ -83,7 +83,7 @@ void init_sonoa_ctx()
sph_haval256_5_init(&sonoa_ctx.haval);
};
int sonoa_hash( void *state, const void *input, int thrid )
int sonoa_hash( void *state, const void *input, int thr_id )
{
uint8_t hash[128] __attribute__ ((aligned (64)));
sonoa_ctx_holder ctx __attribute__ ((aligned (64)));
@@ -132,7 +132,7 @@ int sonoa_hash( void *state, const void *input, int thrid )
sph_echo512_close(&ctx.echo, hash);
#endif
if ( work_restart[thrid].restart ) return 0;
if ( work_restart[thr_id].restart ) return 0;
//
sph_bmw512_init( &ctx.bmw);
@@ -190,7 +190,7 @@ int sonoa_hash( void *state, const void *input, int thrid )
sph_hamsi512(&ctx.hamsi, hash, 64);
sph_hamsi512_close(&ctx.hamsi, hash);
if ( work_restart[thrid].restart ) return 0;
if ( work_restart[thr_id].restart ) return 0;
//
sph_bmw512_init( &ctx.bmw);
@@ -252,7 +252,7 @@ int sonoa_hash( void *state, const void *input, int thrid )
sph_fugue512(&ctx.fugue, hash, 64);
sph_fugue512_close(&ctx.fugue, hash);
if ( work_restart[thrid].restart ) return 0;
if ( work_restart[thr_id].restart ) return 0;
//
sph_bmw512_init( &ctx.bmw);
@@ -336,7 +336,7 @@ int sonoa_hash( void *state, const void *input, int thrid )
sph_shavite512(&ctx.shavite, hash, 64);
sph_shavite512_close(&ctx.shavite, hash);
if ( work_restart[thrid].restart ) return 0;
if ( work_restart[thr_id].restart ) return 0;
//
sph_bmw512_init( &ctx.bmw);
@@ -410,7 +410,7 @@ int sonoa_hash( void *state, const void *input, int thrid )
sph_whirlpool(&ctx.whirlpool, hash, 64);
sph_whirlpool_close(&ctx.whirlpool, hash);
if ( work_restart[thrid].restart ) return 0;
if ( work_restart[thr_id].restart ) return 0;
//
sph_bmw512_init( &ctx.bmw);
sph_bmw512(&ctx.bmw, hash, 64);
@@ -487,7 +487,7 @@ int sonoa_hash( void *state, const void *input, int thrid )
sph_whirlpool(&ctx.whirlpool, hash, 64);
sph_whirlpool_close(&ctx.whirlpool, hash);
if ( work_restart[thrid].restart ) return 0;
if ( work_restart[thr_id].restart ) return 0;
//
sph_bmw512_init( &ctx.bmw);

View File

@@ -57,7 +57,7 @@ union _x17_8way_context_overlay
} __attribute__ ((aligned (64)));
typedef union _x17_8way_context_overlay x17_8way_context_overlay;
int x17_8way_hash( void *state, const void *input )
int x17_8way_hash( void *state, const void *input, int thr_id )
{
uint64_t vhash[8*8] __attribute__ ((aligned (128)));
uint64_t vhashA[8*8] __attribute__ ((aligned (64)));
@@ -234,50 +234,6 @@ int x17_8way_hash( void *state, const void *input )
return 1;
}
int scanhash_x17_8way( struct work *work, uint32_t max_nonce,
uint64_t *hashes_done, struct thr_info *mythr )
{
uint32_t hash32[8*8] __attribute__ ((aligned (128)));
uint32_t vdata[20*8] __attribute__ ((aligned (64)));
uint32_t lane_hash[8] __attribute__ ((aligned (64)));
uint32_t *hash32_d7 = &(hash32[7*8]);
uint32_t *pdata = work->data;
const uint32_t *ptarget = work->target;
const uint32_t first_nonce = pdata[19];
const uint32_t last_nonce = max_nonce - 8;
__m512i *noncev = (__m512i*)vdata + 9;
uint32_t n = first_nonce;
const int thr_id = mythr->id;
const uint32_t targ32_d7 = ptarget[7];
const bool bench = opt_benchmark;
mm512_bswap32_intrlv80_8x64( vdata, pdata );
*noncev = mm512_intrlv_blend_32(
_mm512_set_epi32( n+7, 0, n+6, 0, n+5, 0, n+4, 0,
n+3, 0, n+2, 0, n+1, 0, n, 0 ), *noncev );
do
{
x17_8way_hash( hash32, vdata );
for ( int lane = 0; lane < 8; lane++ )
if ( unlikely( ( hash32_d7[ lane ] <= targ32_d7 ) && !bench ) )
{
extr_lane_8x32( lane_hash, hash32, lane, 256 );
if ( likely( valid_hash( lane_hash, ptarget ) ) )
{
pdata[19] = bswap_32( n + lane );
submit_solution( work, lane_hash, mythr );
}
}
*noncev = _mm512_add_epi32( *noncev,
m512_const1_64( 0x0000000800000000 ) );
n += 8;
} while ( likely( ( n < last_nonce ) && !work_restart[thr_id].restart ) );
pdata[19] = n;
*hashes_done = n - first_nonce;
return 0;
}
#elif defined(X17_4WAY)
union _x17_4way_context_overlay
@@ -302,7 +258,7 @@ union _x17_4way_context_overlay
};
typedef union _x17_4way_context_overlay x17_4way_context_overlay;
int x17_4way_hash( void *state, const void *input )
int x17_4way_hash( void *state, const void *input, int thr_id )
{
uint64_t vhash[8*4] __attribute__ ((aligned (64)));
uint64_t vhashA[8*4] __attribute__ ((aligned (64)));
@@ -405,47 +361,4 @@ int x17_4way_hash( void *state, const void *input )
return 1;
}
int scanhash_x17_4way( struct work *work, uint32_t max_nonce,
uint64_t *hashes_done, struct thr_info *mythr )
{
uint32_t hash32[8*4] __attribute__ ((aligned (64)));
uint32_t vdata[20*4] __attribute__ ((aligned (64)));
uint32_t lane_hash[8] __attribute__ ((aligned (64)));
uint32_t *hash32_d7 = &(hash32[ 7*4 ]);
uint32_t *pdata = work->data;
const uint32_t *ptarget = work->target;
const uint32_t first_nonce = pdata[19];
const uint32_t last_nonce = max_nonce - 4;
__m256i *noncev = (__m256i*)vdata + 9;
uint32_t n = first_nonce;
const int thr_id = mythr->id;
const uint32_t targ32_d7 = ptarget[7];
const bool bench = opt_benchmark;
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
{
x17_4way_hash( hash32, vdata );
for ( int lane = 0; lane < 4; lane++ )
if ( unlikely( hash32_d7[ lane ] <= targ32_d7 && !bench ) )
{
extr_lane_4x32( lane_hash, hash32, lane, 256 );
if ( valid_hash( lane_hash, ptarget ) )
{
pdata[19] = bswap_32( n + lane );
submit_solution( work, lane_hash, mythr );
}
}
*noncev = _mm256_add_epi32( *noncev,
m256_const1_64( 0x0000000400000000 ) );
n += 4;
} while ( likely( ( n <= last_nonce ) && !work_restart[thr_id].restart ) );
pdata[19] = n;
*hashes_done = n - first_nonce;
return 0;
}
#endif

View File

@@ -3,10 +3,10 @@
bool register_x17_algo( algo_gate_t* gate )
{
#if defined (X17_8WAY)
gate->scanhash = (void*)&scanhash_x17_8way;
gate->scanhash = (void*)&scanhash_8way_64in_32out;
gate->hash = (void*)&x17_8way_hash;
#elif defined (X17_4WAY)
gate->scanhash = (void*)&scanhash_x17_4way;
gate->scanhash = (void*)&scanhash_4way_64in_32out;
gate->hash = (void*)&x17_4way_hash;
#else
gate->hash = (void*)&x17_hash;

View File

@@ -14,14 +14,11 @@ bool register_x17_algo( algo_gate_t* gate );
#if defined(X17_8WAY)
int x17_8way_hash( void *state, const void *input );
int scanhash_x17_8way( struct work *work, uint32_t max_nonce,
uint64_t *hashes_done, struct thr_info *mythr );
int x17_8way_hash( void *state, const void *input, int thr_id );
#elif defined(X17_4WAY)
int x17_4way_hash( void *state, const void *input );
int scanhash_x17_4way( struct work *work, uint32_t max_nonce,
uint64_t *hashes_done, struct thr_info *mythr );
int x17_4way_hash( void *state, const void *input, int thr_id );
#endif

View File

@@ -57,7 +57,7 @@ union _xevan_8way_context_overlay
} __attribute__ ((aligned (64)));
typedef union _xevan_8way_context_overlay xevan_8way_context_overlay;
int xevan_8way_hash( void *output, const void *input )
int xevan_8way_hash( void *output, const void *input, int thr_id )
{
uint64_t vhash[16<<3] __attribute__ ((aligned (128)));
uint64_t vhashA[16<<3] __attribute__ ((aligned (64)));
@@ -399,50 +399,6 @@ int xevan_8way_hash( void *output, const void *input )
return 1;
}
int scanhash_xevan_8way( struct work *work, uint32_t max_nonce,
uint64_t *hashes_done, struct thr_info *mythr )
{
uint32_t hash[8*8] __attribute__ ((aligned (128)));
uint32_t vdata[20*8] __attribute__ ((aligned (64)));
uint32_t lane_hash[8] __attribute__ ((aligned (64)));
uint32_t *hashd7 = &(hash[7*8]);
uint32_t *pdata = work->data;
const uint32_t *ptarget = work->target;
const uint32_t first_nonce = pdata[19];
const uint32_t last_nonce = max_nonce - 8;
__m512i *noncev = (__m512i*)vdata + 9;
uint32_t n = first_nonce;
const int thr_id = mythr->id;
const uint32_t targ32 = ptarget[7];
const bool bench = opt_benchmark;
mm512_bswap32_intrlv80_8x64( vdata, pdata );
*noncev = mm512_intrlv_blend_32(
_mm512_set_epi32( n+7, 0, n+6, 0, n+5, 0, n+4, 0,
n+3, 0, n+2, 0, n+1, 0, n, 0 ), *noncev );
do
{
xevan_8way_hash( hash, vdata );
for ( int lane = 0; lane < 8; lane++ )
if ( unlikely( ( hashd7[ lane ] <= targ32 ) && !bench ) )
{
extr_lane_8x32( lane_hash, hash, lane, 256 );
if ( likely( valid_hash( lane_hash, ptarget ) ) )
{
pdata[19] = bswap_32( n + lane );
submit_solution( work, lane_hash, mythr );
}
}
*noncev = _mm512_add_epi32( *noncev,
m512_const1_64( 0x0000000800000000 ) );
n += 8;
} while ( likely( ( n < last_nonce ) && !work_restart[thr_id].restart ) );
pdata[19] = n;
*hashes_done = n - first_nonce;
return 0;
}
#elif defined(XEVAN_4WAY)
union _xevan_4way_context_overlay
@@ -467,7 +423,7 @@ union _xevan_4way_context_overlay
};
typedef union _xevan_4way_context_overlay xevan_4way_context_overlay;
int xevan_4way_hash( void *output, const void *input )
int xevan_4way_hash( void *output, const void *input, int thr_id )
{
uint64_t hash0[16] __attribute__ ((aligned (64)));
uint64_t hash1[16] __attribute__ ((aligned (64)));
@@ -672,47 +628,4 @@ int xevan_4way_hash( void *output, const void *input )
return 1;
}
int scanhash_xevan_4way( struct work *work, uint32_t max_nonce,
uint64_t *hashes_done, struct thr_info *mythr )
{
uint32_t hash[16*4] __attribute__ ((aligned (128)));
uint32_t vdata[20*4] __attribute__ ((aligned (64)));
uint32_t lane_hash[8] __attribute__ ((aligned (64)));
uint32_t *hashd7 = &(hash[7<<2]);
uint32_t *pdata = work->data;
uint32_t *ptarget = work->target;
int thr_id = mythr->id;
__m256i *noncev = (__m256i*)vdata + 9;
const uint32_t targ32 = ptarget[7];
const uint32_t first_nonce = pdata[19];
const uint32_t last_nonce = max_nonce - 4;
uint32_t n = first_nonce;
const bool bench = opt_benchmark;
if ( bench ) ptarget[7] = 0x0cff;
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 {
xevan_4way_hash( hash, vdata );
for ( int lane = 0; lane < 4; lane++ )
if ( unlikely( hashd7[ lane ] <= targ32 ) && ! bench )
{
extr_lane_4x32( lane_hash, hash, lane, 256 );
if ( valid_hash( lane_hash, ptarget ) )
{
pdata[19] = bswap_32( n + lane );
submit_solution( work, lane_hash, mythr );
}
}
*noncev = _mm256_add_epi32( *noncev,
m256_const1_64( 0x0000000400000000 ) );
n += 4;
} while ( likely( ( n < last_nonce ) && !work_restart[thr_id].restart ) );
pdata[19] = n;
*hashes_done = n - first_nonce;
return 0;
}
#endif

View File

@@ -3,10 +3,10 @@
bool register_xevan_algo( algo_gate_t* gate )
{
#if defined (XEVAN_8WAY)
gate->scanhash = (void*)&scanhash_xevan_8way;
gate->scanhash = (void*)&scanhash_8way_64in_32out;
gate->hash = (void*)&xevan_8way_hash;
#elif defined (XEVAN_4WAY)
gate->scanhash = (void*)&scanhash_xevan_4way;
gate->scanhash = (void*)&scanhash_4way_64in_32out;
gate->hash = (void*)&xevan_4way_hash;
#else
init_xevan_ctx();

View File

@@ -14,16 +14,11 @@ bool register_xevan_algo( algo_gate_t* gate );
#if defined(XEVAN_8WAY)
int xevan_8way_hash( void *state, const void *input );
int scanhash_xevan_8way( struct work *work, uint32_t max_nonce,
uint64_t *hashes_done, struct thr_info *mythr );
int xevan_8way_hash( void *state, const void *input, int thr_id );
#elif defined(XEVAN_4WAY)
int xevan_4way_hash( void *state, const void *input );
int scanhash_xevan_4way( struct work *work, uint32_t max_nonce,
uint64_t *hashes_done, struct thr_info *mythr );
//void init_xevan_4way_ctx();
int xevan_4way_hash( void *state, const void *input, int thr_id );
#else

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

View File

@@ -2,8 +2,8 @@
* Copyright 2010 Jeff Garzik
* Copyright 2012-2014 pooler
* Copyright 2014 Lucas Jones
* Copyright 2014 Tanguy Pruvot
* Copyright 2016 Jay D Dee
* Copyright 2014-2016 Tanguy Pruvot
* Copyright 2016-2020 Jay D Dee
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -92,7 +92,7 @@ bool want_longpoll = false;
bool have_longpoll = false;
bool have_gbt = true;
bool allow_getwork = true;
bool want_stratum = true;
bool want_stratum = true; // pretty useless
bool have_stratum = false;
bool allow_mininginfo = true;
bool use_syslog = false;
@@ -215,7 +215,7 @@ static char const short_options[] =
static struct work g_work __attribute__ ((aligned (64))) = {{ 0 }};
time_t g_work_time = 0;
static pthread_mutex_t g_work_lock;
pthread_rwlock_t g_work_lock;
static bool submit_old = false;
char* lp_id;
@@ -398,24 +398,12 @@ void work_copy(struct work *dest, const struct work *src)
int std_get_work_data_size() { return STD_WORK_DATA_SIZE; }
// Default
bool std_le_work_decode( const json_t *val, struct work *work )
bool std_le_work_decode( struct work *work )
{
int i;
const int data_size = algo_gate.get_work_data_size();
const int target_size = sizeof(work->target);
const int adata_sz = data_size / 4;
const int adata_sz = algo_gate.get_work_data_size() / 4;
const int atarget_sz = ARRAY_SIZE(work->target);
if (unlikely( !jobj_binary(val, "data", work->data, data_size) ))
{
applog(LOG_ERR, "JSON invalid data");
return false;
}
if (unlikely( !jobj_binary(val, "target", work->target, target_size) ))
{
applog(LOG_ERR, "JSON invalid target");
return false;
}
for ( i = 0; i < adata_sz; i++ )
work->data[i] = le32dec( work->data + i );
for ( i = 0; i < atarget_sz; i++ )
@@ -423,24 +411,12 @@ bool std_le_work_decode( const json_t *val, struct work *work )
return true;
}
bool std_be_work_decode( const json_t *val, struct work *work )
bool std_be_work_decode( struct work *work )
{
int i;
const int data_size = algo_gate.get_work_data_size();
const int target_size = sizeof(work->target);
const int adata_sz = data_size / 4;
const int adata_sz = algo_gate.get_work_data_size() / 4;
const int atarget_sz = ARRAY_SIZE(work->target);
if (unlikely( !jobj_binary(val, "data", work->data, data_size) ))
{
applog(LOG_ERR, "JSON invalid data");
return false;
}
if (unlikely( !jobj_binary(val, "target", work->target, target_size) ))
{
applog(LOG_ERR, "JSON invalid target");
return false;
}
for ( i = 0; i < adata_sz; i++ )
work->data[i] = be32dec( work->data + i );
for ( i = 0; i < atarget_sz; i++ )
@@ -450,14 +426,31 @@ bool std_be_work_decode( const json_t *val, struct work *work )
static bool work_decode( const json_t *val, struct work *work )
{
if ( !algo_gate.work_decode( val, work ) )
const int data_size = algo_gate.get_work_data_size();
const int target_size = sizeof(work->target);
if (unlikely( !jobj_binary(val, "data", work->data, data_size) ))
{
applog(LOG_ERR, "JSON invalid data");
return false;
}
if (unlikely( !jobj_binary(val, "target", work->target, target_size) ))
{
applog(LOG_ERR, "JSON invalid target");
return false;
}
if ( unlikely( !algo_gate.work_decode( work ) ) )
return false;
if ( !allow_mininginfo )
net_diff = algo_gate.calc_network_diff( work );
work->targetdiff = hash_to_diff( work->target );
stratum_diff = last_targetdiff = work->targetdiff;
work->sharediff = 0;
algo_gate.decode_extra_data( work, &net_blocks );
return true;
}
@@ -477,8 +470,7 @@ static bool get_mininginfo( CURL *curl, struct work *work )
if ( !val && curl_err == -1 )
{
allow_mininginfo = false;
if ( opt_debug )
applog( LOG_DEBUG, "getmininginfo not supported" );
applog( LOG_NOTICE, "\"getmininginfo\" not supported, some stats not available" );
return false;
}
@@ -603,7 +595,6 @@ static bool gbt_work_decode( const json_t *val, struct work *work )
goto out;
}
work->height = (int) json_integer_value( tmp );
applog( LOG_BLUE, "Current block is %d", work->height );
tmp = json_object_get(val, "version");
if ( !tmp || !json_is_integer( tmp ) )
@@ -1117,7 +1108,6 @@ void report_summary_log( bool force )
solved, solved_block_count );
applog2( LOG_INFO, "Hi/Lo Share Diff %.5g / %.5g",
highest_share, lowest_share );
}
bool lowdiff_debug = false;
@@ -1125,7 +1115,7 @@ bool lowdiff_debug = false;
static int share_result( int result, struct work *work,
const char *reason )
{
double share_time = 0., share_ratio = 0.;
double share_time = 0.; //, share_ratio = 0.;
double hashrate = 0.;
int latency = 0;
struct share_stats_t my_stats = {0};
@@ -1137,7 +1127,7 @@ static int share_result( int result, struct work *work,
bool solved = false;
bool stale = false;
char *acol = NULL, *bcol = NULL, *scol = NULL, *rcol = NULL;
// Mutex while we grab a snapshot of the stats.
pthread_mutex_lock( &stats_lock );
if ( likely( share_stats[ s_get_ptr ].submit_time.tv_sec ) )
@@ -1166,8 +1156,11 @@ static int share_result( int result, struct work *work,
sizeof last_submit_time );
}
/*
share_ratio = my_stats.net_diff == 0. ? 0. : my_stats.share_diff /
my_stats.net_diff;
*/
// check result
if ( likely( result ) )
{
@@ -1239,7 +1232,7 @@ static int share_result( int result, struct work *work,
if ( use_colors )
{
bcol = acol = scol = rcol = CL_N;
bcol = acol = scol = rcol = CL_WHT;
if ( likely( result ) )
{
acol = CL_WHT CL_GRN;
@@ -1248,28 +1241,23 @@ static int share_result( int result, struct work *work,
else if ( stale ) scol = CL_WHT CL_YL2;
else rcol = CL_WHT CL_RED;
}
else
bcol = acol = scol = rcol = "\0";
applog( LOG_NOTICE, "%d %s%s %s%s %s%s %s%s" CL_N ", %.3f sec (%dms)",
applog( LOG_NOTICE, "%d %s%s %s%s %s%s %s%s" CL_WHT ", %.3f sec (%dms)",
my_stats.share_count, acol, ares, scol, sres, rcol, rres, bcol,
bres, share_time, latency );
if ( !opt_quiet )
if ( unlikely( opt_debug || !result || solved ) )
{
if ( have_stratum )
applog2( LOG_INFO, "Diff %.5g (%.3g), %sBlock %d" CL_N ", %sJob %s",
my_stats.share_diff, share_ratio, bcol, stratum.block_height,
scol, my_stats.job_id );
applog2( LOG_INFO, "Diff %.5g, Block %d, Job %s",
my_stats.share_diff, stratum.block_height,
my_stats.job_id );
else
{
uint64_t height = work ? work->height : last_block_height;
applog2( LOG_INFO, "Diff %.5g (%.3g), %sBlock %d",
my_stats.share_diff, share_ratio, bcol, height );
}
applog2( LOG_INFO, "Diff %.5g, Block %d",
my_stats.share_diff, work ? work->height : last_block_height );
}
if ( unlikely( opt_debug || !( opt_quiet || result || stale ) ) )
if ( unlikely( !( opt_quiet || result || stale ) ) )
{
uint32_t str[8];
@@ -1582,13 +1570,21 @@ start:
if ( work->height > last_block_height )
{
last_block_height = work->height;
last_targetdiff = net_diff;
applog( LOG_BLUE, "New Block %d, Net Diff %.5g, Ntime %08x",
work->height, net_diff,
bswap_32( work->data[ algo_gate.ntime_index ] ) );
work->data[ algo_gate.ntime_index ] );
if ( !opt_quiet && net_diff && ( net_hashrate > 0. ) )
if ( !opt_quiet )
{
double miner_hr = 0.;
double net_hr = net_hashrate;
char net_hr_units[4] = {0};
char miner_hr_units[4] = {0};
char net_ttf[32];
char miner_ttf[32];
pthread_mutex_lock( &stats_lock );
for ( int i = 0; i < opt_n_threads; i++ )
@@ -1597,28 +1593,27 @@ start:
pthread_mutex_unlock( &stats_lock );
if ( miner_hr > 0. )
{
double net_hr = net_hashrate;
char net_hr_units[4] = {0};
char miner_hr_units[4] = {0};
char net_ttf[32];
char miner_ttf[32];
if ( net_hr > 0. )
sprintf_et( net_ttf, ( net_diff * exp32 ) / net_hr );
else
sprintf( net_ttf, "NA" );
if ( miner_hr > 0. )
sprintf_et( miner_ttf, ( net_diff * exp32 ) / miner_hr );
else
sprintf( miner_ttf, "NA" );
scale_hash_for_display ( &miner_hr, miner_hr_units );
scale_hash_for_display ( &net_hr, net_hr_units );
applog2( LOG_INFO,
"Miner TTF @ %.2f %sh/s %s, Net TTF @ %.2f %sh/s %s",
miner_hr, miner_hr_units, miner_ttf,
net_hr, net_hr_units, net_ttf );
}
miner_hr, miner_hr_units, miner_ttf, net_hr,
net_hr_units, net_ttf );
}
} // work->height > last_block_height
else if ( memcmp( &work->data[1], &g_work.data[1], 32 ) )
applog( LOG_BLUE, "New Work, Ntime %08lx",
bswap_32( work->data[ algo_gate.ntime_index ] ) );
applog( LOG_BLUE, "New Work: Block %d, Net Diff %.5g, Ntime %08x",
work->height, net_diff,
work->data[ algo_gate.ntime_index ] );
} // rc
return rc;
@@ -1832,6 +1827,14 @@ bool submit_solution( struct work *work, const void *hash,
if ( likely( submit_work( thr, work ) ) )
{
update_submit_stats( work, hash );
if unlikely( !have_stratum && !have_longpoll )
{ // block solved, force getwork
pthread_rwlock_wrlock( &g_work_lock );
g_work_time = 0;
pthread_rwlock_unlock( &g_work_lock );
}
if ( !opt_quiet )
{
if ( have_stratum )
@@ -1952,6 +1955,8 @@ 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 )
@@ -1967,6 +1972,8 @@ 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,
@@ -1982,7 +1989,13 @@ 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 ];
pthread_rwlock_wrlock( &g_work_lock );
pthread_mutex_lock( &sctx->work_lock );
free( g_work->job_id );
g_work->job_id = strdup( sctx->job.job_id );
g_work->xnonce2_len = sctx->xnonce2_size;
@@ -1995,36 +2008,40 @@ 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 );
pthread_mutex_unlock( &sctx->work_lock );
// Increment extranonce2
for ( int t = 0; t < sctx->xnonce2_size && !( ++sctx->job.xnonce2[t] ); t++ );
g_work_time = time(NULL);
restart_threads();
if ( opt_debug )
{
unsigned char *xnonce2str = abin2hex( g_work->xnonce2,
g_work->xnonce2_len );
applog( LOG_DEBUG, "DEBUG: job_id='%s' extranonce2=%s ntime=%08x",
g_work->job_id, xnonce2str, swab32( g_work->data[17] ) );
free( xnonce2str );
}
pthread_mutex_unlock( &sctx->work_lock );
pthread_rwlock_unlock( &g_work_lock );
double hr = 0.;
pthread_mutex_lock( &stats_lock );
double hr = 0.;
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 Diff %g, Block %d, Job %s",
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 if ( g_work->job_id )
applog( LOG_BLUE,"New Job %s", g_work->job_id );
else if ( new_job && g_work->job_id )
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 )
{
unsigned char *xnonce2str = abin2hex( g_work->xnonce2,
g_work->xnonce2_len );
applog( LOG_INFO, "Extranonce %s, Block %d, Net Diff %.5g",
xnonce2str, sctx->block_height, net_diff );
free( xnonce2str );
}
// Update data and calculate new estimates.
if ( ( stratum_diff != sctx->job.diff )
@@ -2052,7 +2069,7 @@ static void stratum_gen_work( struct stratum_ctx *sctx, struct work *g_work )
char share_ttf[32];
sprintf_et( block_ttf, ( net_diff * exp32 ) / hr );
sprintf_et( share_ttf, g_work->targetdiff * exp32 / hr );
sprintf_et( share_ttf, ( g_work->targetdiff * exp32 ) / hr );
scale_hash_for_display ( &hr, hr_units );
applog2( LOG_INFO, "TTF @ %.2f %sh/s: Block %s, Share %s",
hr, hr_units, block_ttf, share_ttf );
@@ -2068,10 +2085,8 @@ static void stratum_gen_work( struct stratum_ctx *sctx, struct work *g_work )
if ( net_diff && net_ttf )
{
double net_hr = net_diff * exp32 / net_ttf;
// char net_ttf_str[32];
char net_hr_units[4] = {0};
// sprintf_et( net_ttf_str, net_ttf );
scale_hash_for_display ( &net_hr, net_hr_units );
applog2( LOG_INFO, "Net hash rate (est) %.2f %sh/s",
net_hr, net_hr_units );
@@ -2199,35 +2214,33 @@ static void *miner_thread( void *userdata )
{
if ( have_stratum )
{
pthread_mutex_lock( &g_work_lock );
if ( *nonceptr >= end_nonce )
stratum_gen_work( &stratum, &g_work );
algo_gate.get_new_work( &work, &g_work, thr_id, &end_nonce );
pthread_mutex_unlock( &g_work_lock );
}
else
{
int scantime = have_longpoll ? LP_SCANTIME : opt_scantime;
pthread_mutex_lock( &g_work_lock );
pthread_rwlock_wrlock( &g_work_lock );
if ( time(NULL) - g_work_time >= scantime
|| *nonceptr >= end_nonce )
if ( ( ( time(NULL) - g_work_time )
>= ( have_longpoll ? LP_SCANTIME : opt_scantime ) )
|| ( *nonceptr >= end_nonce ) )
{
if ( unlikely( !get_work( mythr, &g_work ) ) )
{
pthread_rwlock_unlock( &g_work_lock );
applog( LOG_ERR, "work retrieval failed, exiting "
"mining thread %d", thr_id );
pthread_mutex_unlock( &g_work_lock );
goto out;
}
g_work_time = time(NULL);
restart_threads();
}
pthread_rwlock_unlock( &g_work_lock );
}
algo_gate.get_new_work( &work, &g_work, thr_id, &end_nonce );
pthread_mutex_unlock( &g_work_lock );
}
} // do_this_thread
algo_gate.resync_threads( &work );
@@ -2242,7 +2255,7 @@ static void *miner_thread( void *userdata )
// LP_SCANTIME overrides opt_scantime option, is this right?
// adjust max_nonce to meet target scan time. Startum and longpoll
// adjust max_nonce to meet target scan time. Stratum and longpoll
// can go longer because they can rely on restart_threads to signal
// an early abort. get_work on the other hand can't rely on
// restart_threads so need a much shorter scantime
@@ -2313,6 +2326,7 @@ static void *miner_thread( void *userdata )
hashes_done / ( diff.tv_sec + diff.tv_usec * 1e-6 );
pthread_mutex_unlock( &stats_lock );
}
// If unsubmiited nonce(s) found, submit now.
if ( unlikely( nonce_found && !opt_benchmark ) )
{
@@ -2332,42 +2346,53 @@ static void *miner_thread( void *userdata )
// we can't submit twice a block!
if unlikely( !have_stratum && !have_longpoll )
{
pthread_mutex_lock( &g_work_lock );
pthread_rwlock_wrlock( &g_work_lock );
// will force getwork
g_work_time = 0;
pthread_mutex_unlock( &g_work_lock );
pthread_rwlock_unlock( &g_work_lock );
}
}
#if !(defined(__WINDOWS__) || defined(_WIN64) || defined(_WIN32))
// Display CPU temperature and clock rate.
if (!opt_quiet && mythr->id == 0 )
{
int temp = cpu_temp(0);
static struct timeval cpu_temp_time = {0};
timeval_subtract( &diff, &tv_end, &cpu_temp_time );
int wait = temp >= 80 ? 30 : temp >= 70 ? 60 : 120;
if ( ( diff.tv_sec > wait ) || ( temp > hi_temp ) )
// Display CPU temperature and clock rate.
int curr_temp, prev_hi_temp;
static struct timeval cpu_temp_time = {0};
pthread_mutex_lock( &stats_lock );
prev_hi_temp = hi_temp;
curr_temp = cpu_temp(0);
timeval_subtract( &diff, &tv_end, &cpu_temp_time );
if ( curr_temp > hi_temp ) hi_temp = curr_temp;
pthread_mutex_unlock( &stats_lock );
if ( !opt_quiet || ( curr_temp >= 80 ) )
{
int wait_time = curr_temp >= 80 ? 30 : curr_temp >= 70 ? 60 : 120;
if ( ( diff.tv_sec > wait_time ) || ( curr_temp > prev_hi_temp ) )
{
char tempstr[32];
float lo_freq = 0., hi_freq = 0.;
linux_cpu_hilo_freq( &lo_freq, &hi_freq );
memcpy( &cpu_temp_time, &tv_end, sizeof(cpu_temp_time) );
if ( use_colors && ( temp >= 70 ) )
linux_cpu_hilo_freq( &lo_freq, &hi_freq );
if ( use_colors && ( curr_temp >= 70 ) )
{
if ( temp >= 80 )
sprintf( tempstr, "%s%d C%s", CL_WHT CL_RED, temp, CL_N );
if ( curr_temp >= 80 )
sprintf( tempstr, "%s%d C%s", CL_RED, curr_temp, CL_WHT );
else
sprintf( tempstr, "%s%d C%s", CL_WHT CL_YLW, temp, CL_N );
sprintf( tempstr, "%s%d C%s", CL_YLW, curr_temp, CL_WHT );
}
else
sprintf( tempstr, "%d C", temp );
sprintf( tempstr, "%d C", curr_temp );
applog( LOG_NOTICE,"CPU temp: curr %s (max %d), Freq: %.3f/%.3f GHz",
tempstr, hi_temp, lo_freq / 1e6, hi_freq / 1e6 );
if ( temp > hi_temp ) hi_temp = temp;
tempstr, prev_hi_temp, lo_freq / 1e6, hi_freq / 1e6 );
}
}
#endif
// display hashrate
@@ -2393,12 +2418,13 @@ static void *miner_thread( void *userdata )
&& thr_id == opt_n_threads - 1 ) )
{
double hashrate = 0.;
pthread_mutex_lock( &stats_lock );
for ( i = 0; i < opt_n_threads; i++ )
hashrate += thr_hashrates[i];
if ( hashrate != 0. )
{
global_hashrate = hashrate;
pthread_mutex_unlock( &stats_lock );
if ( opt_benchmark )
{
char hr[16];
@@ -2412,7 +2438,6 @@ static void *miner_thread( void *userdata )
hr, hr_units, (uint32_t)cpu_temp(0) );
#endif
}
}
} // benchmark
} // miner_thread loop
@@ -2509,7 +2534,8 @@ start:
res = json_object_get(val, "result");
soval = json_object_get(res, "submitold");
submit_old = soval ? json_is_true(soval) : false;
pthread_mutex_lock(&g_work_lock);
pthread_rwlock_wrlock( &g_work_lock );
// This code has been here for a long time even though job_id isn't used.
// This needs to be changed eventually to test the block height properly
@@ -2543,14 +2569,16 @@ start:
}
}
free(start_job_id);
pthread_mutex_unlock(&g_work_lock);
pthread_rwlock_unlock( &g_work_lock );
json_decref(val);
}
else // !val
{
pthread_mutex_lock(&g_work_lock);
pthread_rwlock_wrlock( &g_work_lock );
g_work_time -= LP_SCANTIME;
pthread_mutex_unlock(&g_work_lock);
pthread_rwlock_unlock( &g_work_lock );
if (err == CURLE_OPERATION_TIMEDOUT)
{
restart_threads();
@@ -2659,12 +2687,8 @@ void std_build_block_header( struct work* g_work, uint32_t version,
void std_build_extraheader( struct work* g_work, struct stratum_ctx* sctx )
{
uchar merkle_tree[64] = { 0 };
size_t t;
algo_gate.gen_merkle_root( merkle_tree, sctx );
// Increment extranonce2
for ( t = 0; t < sctx->xnonce2_size && !( ++sctx->job.xnonce2[t] ); t++ );
// Assemble block header
algo_gate.build_block_header( g_work, le32dec( sctx->job.version ),
(uint32_t*) sctx->job.prevhash, (uint32_t*) merkle_tree,
le32dec( sctx->job.ntime ), le32dec(sctx->job.nbits),
@@ -2703,10 +2727,10 @@ static void *stratum_thread(void *userdata )
while ( !stratum.curl )
{
pthread_mutex_lock( &g_work_lock );
pthread_rwlock_wrlock( &g_work_lock );
g_work_time = 0;
pthread_mutex_unlock( &g_work_lock );
restart_threads();
pthread_rwlock_unlock( &g_work_lock );
// restart_threads();
if ( !stratum_connect( &stratum, stratum.url )
|| !stratum_subscribe( &stratum )
|| !stratum_authorize( &stratum, rpc_user, rpc_pass ) )
@@ -2729,15 +2753,10 @@ 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 || strcmp( stratum.job.job_id, g_work.job_id ) ) )
{
pthread_mutex_lock( &g_work_lock );
if ( stratum.job.job_id && ( !g_work_time
|| ( *get_stratum_job_ntime()
!= g_work.data[ algo_gate.ntime_index ] ) ) )
stratum_gen_work( &stratum, &g_work );
time( &g_work_time );
pthread_mutex_unlock( &g_work_lock );
restart_threads();
}
if ( likely( stratum_socket_full( &stratum, opt_timeout ) ) )
{
@@ -2849,7 +2868,7 @@ void parse_arg(int key, char *arg )
switch( key )
{
case 'a':
case 'a': // algo
get_algo_alias( &arg );
for (i = 1; i < ALGO_COUNT; i++)
{
@@ -2880,37 +2899,41 @@ void parse_arg(int key, char *arg )
}
break;
case 'b':
case 'b': // api-bind
opt_api_enabled = true;
p = strstr(arg, ":");
if (p) {
if ( p )
{
/* ip:port */
if (p - arg > 0) {
if ( p - arg > 0 )
{
opt_api_allow = strdup(arg);
opt_api_allow[p - arg] = '\0';
}
opt_api_listen = atoi(p + 1);
}
else if (arg && strstr(arg, ".")) {
else if ( arg && strstr( arg, "." ) )
{
/* ip only */
free(opt_api_allow);
opt_api_allow = strdup(arg);
opt_api_listen = default_api_listen;
}
else if (arg) {
else if ( arg )
{
/* port or 0 to disable */
opt_api_allow = default_api_allow;
opt_api_listen = atoi(arg);
}
break;
case 1030: /* --api-remote */
case 1030: // api-remote
opt_api_remote = 1;
break;
case 'B':
case 'B': // background
opt_background = true;
use_colors = false;
break;
case 'c': {
case 'c': { // config
json_error_t err;
json_t *config;
@@ -2923,8 +2946,7 @@ void parse_arg(int key, char *arg )
if (err.line < 0)
fprintf(stderr, "%s\n", err.text);
else
fprintf(stderr, "%s:%d: %s\n",
arg, err.line, err.text);
fprintf(stderr, "%s:%d: %s\n", arg, err.line, err.text);
}
else
{
@@ -2933,63 +2955,70 @@ void parse_arg(int key, char *arg )
}
break;
}
case 'q':
opt_quiet = true;
// debug overrides quiet
case 'q': // quiet
if ( !( opt_debug || opt_protocol ) ) opt_quiet = true;
break;
case 'D':
case 'D': // debug
opt_debug = true;
opt_quiet = false;
break;
case 'p':
case 'p': // pass
free(rpc_pass);
rpc_pass = strdup(arg);
strhide(arg);
break;
case 'P':
case 'P': // protocol
opt_protocol = true;
opt_quiet = false;
break;
case 'r':
case 'r': // retries
v = atoi(arg);
if (v < -1 || v > 9999) /* sanity check */
show_usage_and_exit(1);
opt_retries = v;
break;
case 1025:
case 1025: // retry-pause
v = atoi(arg);
if (v < 1 || v > 9999) /* sanity check */
show_usage_and_exit(1);
opt_fail_pause = v;
break;
case 's':
case 's': // scantime
v = atoi(arg);
if (v < 1 || v > 9999) /* sanity check */
show_usage_and_exit(1);
opt_scantime = v;
break;
case 'T':
case 'T': // timeout
v = atoi(arg);
if (v < 1 || v > 99999) /* sanity check */
show_usage_and_exit(1);
opt_timeout = v;
break;
case 't':
case 't': // threads
v = atoi(arg);
if (v < 0 || v > 9999) /* sanity check */
show_usage_and_exit(1);
opt_n_threads = v;
break;
case 'u':
case 'u': // user
free(rpc_user);
rpc_user = strdup(arg);
break;
case 'o': { /* --url */
case 'o': // url
{
char *ap, *hp;
ap = strstr( arg, "://" );
ap = ap ? ap + 3 : arg;
hp = strrchr( arg, '@' );
if (hp) {
if ( hp )
{
*hp = '\0';
p = strchr( ap, ':' );
if (p) {
if ( p )
{
free( rpc_userpass );
rpc_userpass = strdup( ap );
free( rpc_user );
@@ -3002,12 +3031,15 @@ void parse_arg(int key, char *arg )
memmove( p + 1, hp + 1, v );
memset( p + v, 0, hp - p );
hp = p;
} else {
}
else
{
free( rpc_user );
rpc_user = strdup( ap );
}
*hp++ = '@';
} else
}
else
hp = ap;
if ( ap != arg )
{
@@ -3023,10 +3055,12 @@ void parse_arg(int key, char *arg )
rpc_url = strdup(arg);
strcpy(rpc_url + (ap - arg), hp);
short_url = &rpc_url[ap - arg];
} else {
if (*hp == '\0' || *hp == '/') {
fprintf(stderr, "invalid URL -- '%s'\n",
arg);
}
else
{
if ( *hp == '\0' || *hp == '/' )
{
fprintf( stderr, "invalid URL -- '%s'\n", arg );
show_usage_and_exit( 1 );
}
free( rpc_url );
@@ -3037,9 +3071,10 @@ void parse_arg(int key, char *arg )
have_stratum = !opt_benchmark && !strncasecmp( rpc_url, "stratum", 7 );
break;
}
case 'O': /* --userpass */
case 'O': // userpass
p = strchr(arg, ':');
if (!p) {
if (!p)
{
fprintf(stderr, "invalid username:password pair -- '%s'\n", arg);
show_usage_and_exit(1);
}
@@ -3052,7 +3087,7 @@ void parse_arg(int key, char *arg )
rpc_pass = strdup(++p);
strhide(p);
break;
case 'x': /* --proxy */
case 'x': // proxy
if ( !strncasecmp( arg, "socks4://", 9 ) )
opt_proxy_type = CURLPROXY_SOCKS4;
else if ( !strncasecmp( arg, "socks5://", 9 ) )
@@ -3068,42 +3103,42 @@ void parse_arg(int key, char *arg )
free(opt_proxy);
opt_proxy = strdup(arg);
break;
case 1001:
case 1001: // cert
free(opt_cert);
opt_cert = strdup(arg);
break;
case 1002:
case 1002: // no-color
use_colors = false;
break;
case 1003:
case 1003: // no-longpoll
want_longpoll = false;
break;
case 1005:
case 1005: // benchmark
opt_benchmark = true;
want_longpoll = false;
want_stratum = false;
have_stratum = false;
break;
case 1006:
case 1006: // cputest
// print_hash_tests();
exit(0);
case 1007:
case 1007: // no-stratum
want_stratum = false;
opt_extranonce = false;
break;
case 1008:
case 1008: // time-limit
opt_time_limit = atoi(arg);
break;
case 1009:
case 1009: // no-redirect
opt_redirect = false;
break;
case 1010:
case 1010: // no-getwork
allow_getwork = false;
break;
case 1011:
case 1011: // no-gbt
have_gbt = false;
break;
case 1012:
case 1012: // no-extranonce
opt_extranonce = false;
break;
case 1014: // hash-meter
@@ -3113,7 +3148,8 @@ void parse_arg(int key, char *arg )
if ( arg ) coinbase_address = strdup( arg );
break;
case 1015: /* --coinbase-sig */
if (strlen(arg) + 1 > sizeof(coinbase_sig)) {
if ( strlen( arg ) + 1 > sizeof(coinbase_sig) )
{
fprintf( stderr, "coinbase signature too long\n" );
show_usage_and_exit( 1 );
}
@@ -3131,11 +3167,13 @@ void parse_arg(int key, char *arg )
show_usage_and_exit(1);
opt_diff_factor = 1.0/d;
break;
case 'S':
#ifdef HAVE_SYSLOG_H
case 'S': // syslog
use_syslog = true;
use_colors = false;
break;
case 1020:
#endif
case 1020: // cpu-affinity
p = strstr(arg, "0x");
if ( p )
ul = strtoull( p, NULL, 16 );
@@ -3153,7 +3191,7 @@ void parse_arg(int key, char *arg )
opt_affinity = ul;
#endif
break;
case 1021:
case 1021: // cpu-priority
v = atoi(arg);
if (v < 0 || v > 5) /* sanity check */
show_usage_and_exit(1);
@@ -3612,7 +3650,7 @@ int main(int argc, char *argv[])
if ( !check_cpu_capability() ) exit(1);
pthread_mutex_init( &stats_lock, NULL );
pthread_mutex_init( &g_work_lock, NULL );
pthread_rwlock_init( &g_work_lock, NULL );
pthread_mutex_init( &stratum.sock_lock, NULL );
pthread_mutex_init( &stratum.work_lock, NULL );
@@ -3772,7 +3810,7 @@ int main(int argc, char *argv[])
return 1;
}
}
if (want_stratum)
if ( have_stratum )
{
if ( opt_debug )
applog(LOG_INFO,"Creating stratum thread");

26
miner.h
View File

@@ -83,6 +83,8 @@ enum {
};
#endif
extern bool is_power_of_2( int n );
static inline bool is_windows(void)
{
#ifdef WIN32
@@ -378,36 +380,25 @@ void cpu_brand_string( char* s );
float cpu_temp( int core );
*/
struct work {
uint32_t data[48] __attribute__ ((aligned (64)));
struct work
{
uint32_t target[8] __attribute__ ((aligned (64)));
uint32_t data[48] __attribute__ ((aligned (64)));
double targetdiff;
// double shareratio;
double sharediff;
double stratum_diff;
int height;
char *txs;
char *workid;
char *job_id;
size_t xnonce2_len;
unsigned char *xnonce2;
bool sapling;
bool stale;
// x16rt
uint32_t merkleroothash[8];
uint32_t witmerkleroothash[8];
uint32_t denom10[8];
uint32_t denom100[8];
uint32_t denom1000[8];
uint32_t denom10000[8];
} __attribute__ ((aligned (64)));
struct stratum_job {
struct stratum_job
{
unsigned char prevhash[32];
unsigned char final_sapling_hash[32];
char *job_id;
@@ -421,7 +412,7 @@ struct stratum_job {
unsigned char ntime[4];
double diff;
bool clean;
// for x16rt
// for x16rt-veil
unsigned char extra[64];
unsigned char denom10[32];
unsigned char denom100[32];
@@ -756,6 +747,7 @@ extern double opt_diff_factor;
extern double opt_target_factor;
extern bool opt_randomize;
extern bool allow_mininginfo;
extern pthread_rwlock_t g_work_lock;
extern time_t g_work_time;
extern bool opt_stratum_stats;
extern int num_cpus;

View File

@@ -375,10 +375,10 @@ static inline void memcpy_512( __m512i *dst, const __m512i *src, const int n )
// Generic for odd rotations
#define mm512_ror_x64( v, n ) _mm512_alignr_epi64( v, v, n )
#define mm512_rol_x64( v, n ) _mm512_alignr_epi64( v, v, 8-n )
#define mm512_rol_x64( v, n ) _mm512_alignr_epi64( v, v, 8-(n) )
#define mm512_ror_x32( v, n ) _mm512_alignr_epi32( v, v, n )
#define mm512_rol_x32( v, n ) _mm512_alignr_epi32( v, v, 16-n )
#define mm512_rol_x32( v, n ) _mm512_alignr_epi32( v, v, 16-(n) )
#define mm512_ror_1x16( v ) \
_mm512_permutexvar_epi16( m512_const_64( \

11
util.c
View File

@@ -81,6 +81,15 @@ struct thread_q {
pthread_cond_t cond;
};
bool is_power_of_2( int n )
{
while ( n > 1 )
{
if ( n % 2 != 0 ) return false;
n = n / 2;
}
return true;
}
void applog2( int prio, const char *fmt, ... )
{
@@ -609,6 +618,8 @@ json_t *json_rpc_call(CURL *curl, const char *url,
goto err_out;
}
// want_stratum is useless, and so is this code it seems. Nothing in
// hi appears to be set.
/* If X-Stratum was found, activate Stratum */
if (want_stratum && hi.stratum_url &&
!strncasecmp(hi.stratum_url, "stratum+tcp://", 14)) {