add SIMD implementation for DETI coin mining using AVX and AVX2, changes needed

This commit is contained in:
RubenCGomes 2025-11-02 22:39:33 +00:00
parent 7e901dbfb7
commit 845884a11c
No known key found for this signature in database
GPG Key ID: 0D213021197E3EE0
1 changed files with 287 additions and 0 deletions

287
aad_coin_miner_simd.c Normal file
View File

@ -0,0 +1,287 @@
//
// Arquiteturas de Alto Desempenho 2025/2026
//
// DETI Coin Miner - SIMD implementation (AVX/AVX2/AVX512F)
//
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include "aad_data_types.h"
#include "aad_utilities.h"
#include "aad_sha1_cpu.h"
#include "aad_vault.h"
static volatile int keep_running = 1;
void signal_handler(int signum)
{
(void)signum;
keep_running = 0;
}
//
// check if a hash starts with aad20250
//
static int is_valid_coin(u32_t *hash)
{
return hash[0] == 0xAAD20250u;
}
//
// 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)
{
for(int lane = 0; lane < simd_width; lane++)
{
u32_t coin[14];
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
for(int idx = 0; idx < 14; idx++)
{
interleaved_data[idx * simd_width + lane] = coin[idx];
}
}
}
//
// extract individual hashes from interleaved hash data
//
static void extract_hashes(u32_t *interleaved_hash, u32_t hashes[][5], int simd_width)
{
for(int lane = 0; lane < simd_width; lane++)
{
for(int idx = 0; idx < 5; idx++)
{
hashes[lane][idx] = interleaved_hash[idx * simd_width + lane];
}
}
}
//
// extract individual coins from interleaved data
//
static void extract_coins(u32_t *interleaved_data, u32_t coins[][14], int simd_width)
{
for(int lane = 0; lane < simd_width; lane++)
{
for(int idx = 0; idx < 14; idx++)
{
coins[lane][idx] = interleaved_data[idx * simd_width + lane];
}
}
}
#if defined(__AVX__)
//
// mine DETI coins using AVX (4-way SIMD)
//
__attribute__((unused))
static void mine_coins_avx(u64_t max_attempts)
{
const int SIMD_WIDTH = 4;
u32_t base_coin[14];
u32_t interleaved_data[14 * SIMD_WIDTH] __attribute__((aligned(16)));
u32_t interleaved_hash[5 * SIMD_WIDTH] __attribute__((aligned(16)));
u64_t attempts = 0;
u32_t coins_found = 0;
// Initialize base coin template
memset(base_coin, 0, sizeof(base_coin));
((u08_t *)base_coin)[0x0 ^ 3] = 'D';
((u08_t *)base_coin)[0x1 ^ 3] = 'E';
((u08_t *)base_coin)[0x2 ^ 3] = 'T';
((u08_t *)base_coin)[0x3 ^ 3] = 'I';
((u08_t *)base_coin)[0x4 ^ 3] = ' ';
((u08_t *)base_coin)[0x5 ^ 3] = 'c';
((u08_t *)base_coin)[0x6 ^ 3] = 'o';
((u08_t *)base_coin)[0x7 ^ 3] = 'i';
((u08_t *)base_coin)[0x8 ^ 3] = 'n';
((u08_t *)base_coin)[0x9 ^ 3] = ' ';
((u08_t *)base_coin)[0xa ^ 3] = '2';
((u08_t *)base_coin)[0xb ^ 3] = ' ';
((u08_t *)base_coin)[0x36 ^ 3] = '\n';
((u08_t *)base_coin)[0x37 ^ 3] = 0x80;
// Initialize variable part
for(int i = 12; i < 54; i++)
((u08_t *)base_coin)[i ^ 3] = 'A';
printf("Mining DETI coins using AVX (4-way SIMD)...\n");
printf("Press Ctrl+C to stop\n\n");
time_measurement();
while(keep_running && (max_attempts == 0 || attempts < max_attempts))
{
// Prepare coins for this batch
prepare_coins(base_coin, interleaved_data, SIMD_WIDTH, attempts);
// Compute SHA1 hashes
sha1_avx((v4si *)interleaved_data, (v4si *)interleaved_hash);
attempts += SIMD_WIDTH;
// Check each lane for valid coins
u32_t hashes[SIMD_WIDTH][5];
extract_hashes(interleaved_hash, hashes, SIMD_WIDTH);
for(int lane = 0; lane < SIMD_WIDTH; lane++)
{
if(is_valid_coin(hashes[lane]))
{
coins_found++;
u32_t coins[SIMD_WIDTH][14];
extract_coins(interleaved_data, coins, SIMD_WIDTH);
printf("COIN FOUND! (attempt %llu, lane %d)\n",
(unsigned long long)(attempts - SIMD_WIDTH + lane), lane);
save_coin(coins[lane]);
}
}
// Print progress every 1M attempts
if(attempts % 1000000 < SIMD_WIDTH)
{
printf("Attempts: %llu, Coins: %u\n",
(unsigned long long)attempts, coins_found);
}
}
time_measurement();
double total_time = wall_time_delta();
printf("\n=== Mining Statistics ===\n");
printf("Total attempts: %llu\n", (unsigned long long)attempts);
printf("Total time: %.2f seconds\n", total_time);
printf("Average rate: %.2f attempts/second\n", attempts / total_time);
printf("Coins found: %u\n", coins_found);
save_coin(NULL);
}
#endif
#if defined(__AVX2__)
//
// mine DETI coins using AVX2 (8-way SIMD)
//
__attribute__((unused))
static void mine_coins_avx2(u64_t max_attempts)
{
const int SIMD_WIDTH = 8;
u32_t base_coin[14];
u32_t interleaved_data[14 * SIMD_WIDTH] __attribute__((aligned(32)));
u32_t interleaved_hash[5 * SIMD_WIDTH] __attribute__((aligned(32)));
u64_t attempts = 0;
u32_t coins_found = 0;
// Initialize base coin template
memset(base_coin, 0, sizeof(base_coin));
((u08_t *)base_coin)[0x0 ^ 3] = 'D';
((u08_t *)base_coin)[0x1 ^ 3] = 'E';
((u08_t *)base_coin)[0x2 ^ 3] = 'T';
((u08_t *)base_coin)[0x3 ^ 3] = 'I';
((u08_t *)base_coin)[0x4 ^ 3] = ' ';
((u08_t *)base_coin)[0x5 ^ 3] = 'c';
((u08_t *)base_coin)[0x6 ^ 3] = 'o';
((u08_t *)base_coin)[0x7 ^ 3] = 'i';
((u08_t *)base_coin)[0x8 ^ 3] = 'n';
((u08_t *)base_coin)[0x9 ^ 3] = ' ';
((u08_t *)base_coin)[0xa ^ 3] = '2';
((u08_t *)base_coin)[0xb ^ 3] = ' ';
((u08_t *)base_coin)[0x36 ^ 3] = '\n';
((u08_t *)base_coin)[0x37 ^ 3] = 0x80;
for(int i = 12; i < 54; i++)
((u08_t *)base_coin)[i ^ 3] = 'A';
printf("Mining DETI coins using AVX2 (8-way SIMD)...\n");
printf("Press Ctrl+C to stop\n\n");
time_measurement();
while(keep_running && (max_attempts == 0 || attempts < max_attempts))
{
prepare_coins(base_coin, interleaved_data, SIMD_WIDTH, attempts);
sha1_avx2((v8si *)interleaved_data, (v8si *)interleaved_hash);
attempts += SIMD_WIDTH;
u32_t hashes[SIMD_WIDTH][5];
extract_hashes(interleaved_hash, hashes, SIMD_WIDTH);
for(int lane = 0; lane < SIMD_WIDTH; lane++)
{
if(is_valid_coin(hashes[lane]))
{
coins_found++;
u32_t coins[SIMD_WIDTH][14];
extract_coins(interleaved_data, coins, SIMD_WIDTH);
printf("COIN FOUND! (attempt %llu, lane %d)\n",
(unsigned long long)(attempts - SIMD_WIDTH + lane), lane);
save_coin(coins[lane]);
}
}
if(attempts % 1000000 < SIMD_WIDTH)
{
printf("Attempts: %llu, Coins: %u\n",
(unsigned long long)attempts, coins_found);
}
}
time_measurement();
double total_time = wall_time_delta();
printf("\n=== Mining Statistics ===\n");
printf("Total attempts: %llu\n", (unsigned long long)attempts);
printf("Total time: %.2f seconds\n", total_time);
printf("Average rate: %.2f attempts/second\n", attempts / total_time);
printf("Coins found: %u\n", coins_found);
save_coin(NULL);
}
#endif
int main(int argc, char *argv[])
{
u64_t max_attempts = 0;
signal(SIGINT, signal_handler);
if(argc > 1)
max_attempts = strtoull(argv[1], NULL, 10);
#if defined(__AVX2__)
printf("Using AVX2 implementation\n");
mine_coins_avx2(max_attempts);
#elif defined(__AVX__)
printf("Using AVX implementation\n");
mine_coins_avx(max_attempts);
#else
printf("Error: No SIMD instruction set available. Compile with -mavx or -mavx2\n");
return 1;
#endif
return 0;
}