Adapt SIMD miner to use CPU miner's counter logic

Co-authored-by: RubenCGomes <116815718+RubenCGomes@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot] 2025-11-02 23:18:04 +00:00
parent d980e4775c
commit d0f5425f78
4 changed files with 68 additions and 30 deletions

5
.gitignore vendored
View File

@ -60,3 +60,8 @@ CMakeUserPresets.json
*.ptx *.ptx
*.cubin *.cubin
*.fatbin *.fatbin
# Coin miner executables
coin_miner_cpu
coin_miner_simd
coin_miner_cuda

View File

@ -30,39 +30,61 @@ static int is_valid_coin(u32_t *hash)
return hash[0] == 0xAAD20250u; return hash[0] == 0xAAD20250u;
} }
//
// increment coin variable part using the same logic as CPU miner
// returns 0 if overflow (all positions wrapped around), 1 otherwise
//
static int increment_coin(u32_t coin[14])
{
// Update the variable part (simple counter-based approach)
// Increment from the end to beginning (positions 53 down to 12)
int pos = 53;
while(pos >= 12)
{
u08_t *byte = &((u08_t *)coin)[pos ^ 3];
if(*byte == '\n' || *byte == 0x80)
*byte = 32; // Start from space
(*byte)++;
// Skip newline character
if(*byte == '\n')
(*byte)++;
// Wrap around at 127 (printable ASCII limit)
if(*byte >= 127)
{
*byte = 32; // Reset to space
pos--; // Carry to next position
}
else
{
break; // No carry needed
}
}
// Return 0 if we carried all the way through (overflow), 1 otherwise
return (pos >= 12);
}
// //
// prepare interleaved data for SIMD processing // prepare interleaved data for SIMD processing
// //
static void prepare_coins(u32_t base_coin[14], u32_t *interleaved_data, int simd_width, u64_t base_counter) static void prepare_coins(u32_t base_coin[14], u32_t *interleaved_data, int simd_width)
{ {
for(int lane = 0; lane < simd_width; lane++) for(int lane = 0; lane < simd_width; lane++)
{ {
u32_t coin[14]; u32_t coin[14];
memcpy(coin, base_coin, sizeof(coin)); memcpy(coin, base_coin, sizeof(coin));
// Modify the coin for this lane (encode counter in the variable part)
u64_t counter = base_counter + lane;
for(int i = 12; i < 20 && i < 54; i++)
{
int shift = (19 - i) * 8;
if(shift >= 0 && shift < 64)
{
u08_t byte = (counter >> shift) & 0xFF;
// Map to ASCII printable range (32-126, excluding newline position)
if(byte == '\n' || byte >= 0x80)
byte = 'X';
// Ensure byte is in printable ASCII range (32-126)
// Map all values to ASCII printable characters: space (32) to tilde (126)
// byte = 32 + (byte % 95);
((u08_t *)coin)[i ^ 3] = byte;
}
}
// Interleave the data // Interleave the data
for(int idx = 0; idx < 14; idx++) for(int idx = 0; idx < 14; idx++)
{ {
interleaved_data[idx * simd_width + lane] = coin[idx]; interleaved_data[idx * simd_width + lane] = coin[idx];
} }
// Increment the base coin for the next lane
increment_coin(base_coin);
} }
} }
@ -125,19 +147,21 @@ static void mine_coins_avx(u64_t max_attempts)
((u08_t *)base_coin)[0x36 ^ 3] = '\n'; ((u08_t *)base_coin)[0x36 ^ 3] = '\n';
((u08_t *)base_coin)[0x37 ^ 3] = 0x80; ((u08_t *)base_coin)[0x37 ^ 3] = 0x80;
// Initialize variable part // Initialize variable part with the same pattern as CPU miner
for(int i = 12; i < 54; i++) for(int i = 12; i < 54; i++)
((u08_t *)base_coin)[i ^ 3] = 'A'; ((u08_t *)base_coin)[i ^ 3] = 'A' + (i - 12) % 26;
printf("Mining DETI coins using AVX (4-way SIMD)...\n"); printf("Mining DETI coins using AVX (4-way SIMD)...\n");
printf("Press Ctrl+C to stop\n\n"); printf("Press Ctrl+C to stop\n\n");
time_measurement(); time_measurement();
time_measurement();
double start_time = wall_time_delta();
while(keep_running && (max_attempts == 0 || attempts < max_attempts)) while(keep_running && (max_attempts == 0 || attempts < max_attempts))
{ {
// Prepare coins for this batch // Prepare coins for this batch
prepare_coins(base_coin, interleaved_data, SIMD_WIDTH, attempts); prepare_coins(base_coin, interleaved_data, SIMD_WIDTH);
// Compute SHA1 hashes // Compute SHA1 hashes
sha1_avx((v4si *)interleaved_data, (v4si *)interleaved_hash); sha1_avx((v4si *)interleaved_data, (v4si *)interleaved_hash);
@ -163,13 +187,16 @@ static void mine_coins_avx(u64_t max_attempts)
// Print progress every 1M attempts // Print progress every 1M attempts
if(attempts % 1000000 < SIMD_WIDTH) if(attempts % 1000000 < SIMD_WIDTH)
{ {
printf("Attempts: %llu, Coins: %u\n", time_measurement();
(unsigned long long)attempts, coins_found); double current_time = wall_time_delta() - start_time;
double rate = attempts / current_time;
printf("Attempts: %llu, Rate: %.2f MH/s, Coins: %u\n",
(unsigned long long)attempts, rate / 1e6, coins_found);
} }
} }
time_measurement(); time_measurement();
double total_time = wall_time_delta(); double total_time = wall_time_delta() - start_time;
printf("\n=== Mining Statistics ===\n"); printf("\n=== Mining Statistics ===\n");
printf("Total attempts: %llu\n", (unsigned long long)attempts); printf("Total attempts: %llu\n", (unsigned long long)attempts);
@ -212,17 +239,20 @@ static void mine_coins_avx2(u64_t max_attempts)
((u08_t *)base_coin)[0x36 ^ 3] = '\n'; ((u08_t *)base_coin)[0x36 ^ 3] = '\n';
((u08_t *)base_coin)[0x37 ^ 3] = 0x80; ((u08_t *)base_coin)[0x37 ^ 3] = 0x80;
// Initialize variable part with the same pattern as CPU miner
for(int i = 12; i < 54; i++) for(int i = 12; i < 54; i++)
((u08_t *)base_coin)[i ^ 3] = 'A'; ((u08_t *)base_coin)[i ^ 3] = 'A' + (i - 12) % 26;
printf("Mining DETI coins using AVX2 (8-way SIMD)...\n"); printf("Mining DETI coins using AVX2 (8-way SIMD)...\n");
printf("Press Ctrl+C to stop\n\n"); printf("Press Ctrl+C to stop\n\n");
time_measurement(); time_measurement();
time_measurement();
double start_time = wall_time_delta();
while(keep_running && (max_attempts == 0 || attempts < max_attempts)) while(keep_running && (max_attempts == 0 || attempts < max_attempts))
{ {
prepare_coins(base_coin, interleaved_data, SIMD_WIDTH, attempts); prepare_coins(base_coin, interleaved_data, SIMD_WIDTH);
sha1_avx2((v8si *)interleaved_data, (v8si *)interleaved_hash); sha1_avx2((v8si *)interleaved_data, (v8si *)interleaved_hash);
attempts += SIMD_WIDTH; attempts += SIMD_WIDTH;
@ -244,13 +274,16 @@ static void mine_coins_avx2(u64_t max_attempts)
if(attempts % 1000000 < SIMD_WIDTH) if(attempts % 1000000 < SIMD_WIDTH)
{ {
printf("Attempts: %llu, Coins: %u\n", time_measurement();
(unsigned long long)attempts, coins_found); double current_time = wall_time_delta() - start_time;
double rate = attempts / current_time;
printf("Attempts: %llu, Rate: %.2f MH/s, Coins: %u\n",
(unsigned long long)attempts, rate / 1e6, coins_found);
} }
} }
time_measurement(); time_measurement();
double total_time = wall_time_delta(); double total_time = wall_time_delta() - start_time;
printf("\n=== Mining Statistics ===\n"); printf("\n=== Mining Statistics ===\n");
printf("Total attempts: %llu\n", (unsigned long long)attempts); printf("Total attempts: %llu\n", (unsigned long long)attempts);

Binary file not shown.

Binary file not shown.