// // Arquiteturas de Alto Desempenho 2025/2026 // // DETI Coin Miner - SIMD implementation (AVX/AVX2/AVX512F) // #include #include #include #include #include #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; } // // 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]) { // Increment the variable part using byte-by-byte logic with carry // 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 // static void prepare_coins(u32_t base_coin[14], u32_t *interleaved_data, int simd_width) { for(int lane = 0; lane < simd_width; lane++) { u32_t coin[14]; memcpy(coin, base_coin, sizeof(coin)); // Interleave the data for(int idx = 0; idx < 14; idx++) { interleaved_data[idx * simd_width + lane] = coin[idx]; } // Increment the base coin for the next lane increment_coin(base_coin); } } // // 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 with A-Z cycling pattern (same as CPU miner) for(int i = 12; i < 54; i++) ((u08_t *)base_coin)[i ^ 3] = 'A' + (i - 12) % 26; printf("Mining DETI coins using AVX (4-way SIMD)...\n"); printf("Press Ctrl+C to stop\n\n"); time_measurement(); time_measurement(); double start_time = wall_time_delta(); while(keep_running && (max_attempts == 0 || attempts < max_attempts)) { // Prepare coins for this batch prepare_coins(base_coin, interleaved_data, SIMD_WIDTH); // 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) { time_measurement(); 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(); double total_time = wall_time_delta() - start_time; 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; // Initialize variable part with A-Z cycling pattern (same as CPU miner) for(int i = 12; i < 54; i++) ((u08_t *)base_coin)[i ^ 3] = 'A' + (i - 12) % 26; printf("Mining DETI coins using AVX2 (8-way SIMD)...\n"); printf("Press Ctrl+C to stop\n\n"); time_measurement(); time_measurement(); double start_time = wall_time_delta(); while(keep_running && (max_attempts == 0 || attempts < max_attempts)) { prepare_coins(base_coin, interleaved_data, SIMD_WIDTH); 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) { time_measurement(); 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(); double total_time = wall_time_delta() - start_time; 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__) #include // // mine DETI coins using AVX2 (8-way SIMD) + OpenMP // __attribute__((unused)) static void mine_coins_avx2_omp(u64_t max_attempts) { const int SIMD_WIDTH = 8; int num_threads = omp_get_max_threads(); u64_t attempts = 0; u32_t coins_found = 0; printf("Mining DETI coins using AVX2 (8-way SIMD) + OpenMP (%d threads)...\n", num_threads); printf("Press Ctrl+C to stop\n\n"); time_measurement(); time_measurement(); double start_time = wall_time_delta(); #pragma omp parallel { 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))); // u32_t thread_coins_found = 0; u64_t thread_attempts = 0; // Initialize base coin template (unique per thread) 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 with A-Z cycling pattern (offset per thread) int thread_id = omp_get_thread_num(); for(int i = 12; i < 54; i++) ((u08_t *)base_coin)[i ^ 3] = 'A' + ((i - 12 + thread_id * SIMD_WIDTH) % 26); while(keep_running && (max_attempts == 0 || (attempts + thread_attempts) < max_attempts)) { prepare_coins(base_coin, interleaved_data, SIMD_WIDTH); sha1_avx2((v8si *)interleaved_data, (v8si *)interleaved_hash); thread_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])) { #pragma omp critical { coins_found++; u32_t coins[SIMD_WIDTH][14]; extract_coins(interleaved_data, coins, SIMD_WIDTH); printf("COIN FOUND! (attempt %llu, thread %d, lane %d)\n", (unsigned long long)(attempts + thread_attempts - SIMD_WIDTH + lane), thread_id, lane); save_coin(coins[lane]); } } } // Print progress every 1M attempts (per thread) if(thread_attempts % 1000000 < SIMD_WIDTH) { #pragma omp critical { time_measurement(); double current_time = wall_time_delta() - start_time; double rate = (attempts + thread_attempts) / current_time; printf("Attempts: %llu, Rate: %.2f MH/s, Coins: %u\n", (unsigned long long)(attempts + thread_attempts), rate / 1e6, coins_found); } } } #pragma omp atomic attempts += thread_attempts; } time_measurement(); double total_time = wall_time_delta() - start_time; 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__) if(argc > 2 && strcmp(argv[2], "omp") == 0) { printf("Using AVX2 + OpenMP implementation\n"); mine_coins_avx2_omp(max_attempts); } else { 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; }