CLI arguments
Signed-off-by: Tiago Garcia <tiago.rgarcia@ua.pt>
This commit is contained in:
parent
0f2225f1d4
commit
2a178133a6
|
|
@ -9,6 +9,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <getopt.h>
|
||||||
#include "aad_data_types.h"
|
#include "aad_data_types.h"
|
||||||
#include "aad_utilities.h"
|
#include "aad_utilities.h"
|
||||||
#include "aad_sha1_cpu.h"
|
#include "aad_sha1_cpu.h"
|
||||||
|
|
@ -41,7 +42,7 @@ static double get_wall_time(void)
|
||||||
//
|
//
|
||||||
// mine DETI coins using the CPU (no SIMD)
|
// mine DETI coins using the CPU (no SIMD)
|
||||||
//
|
//
|
||||||
static void mine_coins_cpu(u64_t max_attempts)
|
static void mine_coins_cpu(u64_t max_attempts, double max_time)
|
||||||
{
|
{
|
||||||
u32_t coin[14];
|
u32_t coin[14];
|
||||||
u32_t hash[5];
|
u32_t hash[5];
|
||||||
|
|
@ -75,12 +76,30 @@ static void mine_coins_cpu(u64_t max_attempts)
|
||||||
((u08_t *)coin)[i ^ 3] = 'A' + (i - 12) % 26;
|
((u08_t *)coin)[i ^ 3] = 'A' + (i - 12) % 26;
|
||||||
|
|
||||||
printf("Mining DETI coins using CPU (no SIMD)...\n");
|
printf("Mining DETI coins using CPU (no SIMD)...\n");
|
||||||
|
if(max_attempts > 0 && max_time > 0)
|
||||||
|
printf("Will stop after %llu attempts OR %.2f seconds (whichever comes first)\n",
|
||||||
|
(unsigned long long)max_attempts, max_time);
|
||||||
|
else if(max_attempts > 0)
|
||||||
|
printf("Will stop after %llu attempts\n", (unsigned long long)max_attempts);
|
||||||
|
else if(max_time > 0)
|
||||||
|
printf("Will stop after %.2f seconds\n", max_time);
|
||||||
|
else
|
||||||
|
printf("Running indefinitely until Ctrl+C...\n");
|
||||||
|
|
||||||
printf("Press Ctrl+C to stop\n\n");
|
printf("Press Ctrl+C to stop\n\n");
|
||||||
|
|
||||||
double start_time = get_wall_time();
|
double start_time = get_wall_time();
|
||||||
|
|
||||||
while(keep_running && (max_attempts == 0 || attempts < max_attempts))
|
while(keep_running)
|
||||||
{
|
{
|
||||||
|
// Check stopping conditions
|
||||||
|
if(max_attempts > 0 && attempts >= max_attempts)
|
||||||
|
break;
|
||||||
|
|
||||||
|
double elapsed = get_wall_time() - start_time;
|
||||||
|
if(max_time > 0 && elapsed >= max_time)
|
||||||
|
break;
|
||||||
|
|
||||||
// Compute SHA1 hash
|
// Compute SHA1 hash
|
||||||
sha1(coin, hash);
|
sha1(coin, hash);
|
||||||
attempts++;
|
attempts++;
|
||||||
|
|
@ -123,7 +142,7 @@ static void mine_coins_cpu(u64_t max_attempts)
|
||||||
// Print progress every 1M attempts
|
// Print progress every 1M attempts
|
||||||
if(attempts % 1000000 == 0)
|
if(attempts % 1000000 == 0)
|
||||||
{
|
{
|
||||||
double elapsed = get_wall_time() - start_time;
|
elapsed = get_wall_time() - start_time;
|
||||||
double rate = attempts / elapsed;
|
double rate = attempts / elapsed;
|
||||||
printf("Attempts: %llu, Rate: %.2f MH/s, Coins: %u, Elapsed: %.2fs\n",
|
printf("Attempts: %llu, Rate: %.2f MH/s, Coins: %u, Elapsed: %.2fs\n",
|
||||||
(unsigned long long)attempts, rate / 1e6, coins_found, elapsed);
|
(unsigned long long)attempts, rate / 1e6, coins_found, elapsed);
|
||||||
|
|
@ -142,25 +161,50 @@ static void mine_coins_cpu(u64_t max_attempts)
|
||||||
save_coin(NULL);
|
save_coin(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void print_usage(const char *prog_name)
|
||||||
|
{
|
||||||
|
printf("Usage: %s [OPTIONS]\n", prog_name);
|
||||||
|
printf("Options:\n");
|
||||||
|
printf(" -a <attempts> Maximum number of attempts\n");
|
||||||
|
printf(" -t <seconds> Maximum time in seconds\n");
|
||||||
|
printf(" -h Show this help message\n");
|
||||||
|
printf("\nExamples:\n");
|
||||||
|
printf(" %s -a 1000000 # Run for 1M attempts\n", prog_name);
|
||||||
|
printf(" %s -t 60 # Run for 60 seconds\n", prog_name);
|
||||||
|
printf(" %s -a 1000000 -t 60 # Stop at 1M attempts OR 60s (whichever first)\n", prog_name);
|
||||||
|
printf(" %s # Run indefinitely until Ctrl+C\n", prog_name);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
u64_t max_attempts = 0;
|
u64_t max_attempts = 0;
|
||||||
|
double max_time = 0;
|
||||||
|
int opt;
|
||||||
|
|
||||||
// Set up signal handler for graceful shutdown
|
// Set up signal handler for graceful shutdown
|
||||||
signal(SIGINT, signal_handler);
|
signal(SIGINT, signal_handler);
|
||||||
|
|
||||||
if(argc > 1)
|
// Parse command line options
|
||||||
|
while((opt = getopt(argc, argv, "a:t:h")) != -1)
|
||||||
{
|
{
|
||||||
max_attempts = strtoull(argv[1], NULL, 10);
|
switch(opt)
|
||||||
printf("Will perform %llu attempts\n", (unsigned long long)max_attempts);
|
{
|
||||||
|
case 'a':
|
||||||
|
max_attempts = strtoull(optarg, NULL, 10);
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
max_time = atof(optarg);
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
print_usage(argv[0]);
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
print_usage(argv[0]);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("Usage: %s [max_attempts]\n", argv[0]);
|
|
||||||
printf("Running indefinitely until Ctrl+C...\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mine_coins_cpu(max_attempts);
|
mine_coins_cpu(max_attempts, max_time);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <getopt.h>
|
||||||
#include "aad_data_types.h"
|
#include "aad_data_types.h"
|
||||||
#include "aad_utilities.h"
|
#include "aad_utilities.h"
|
||||||
#include "aad_sha1_cpu.h"
|
#include "aad_sha1_cpu.h"
|
||||||
|
|
@ -26,6 +27,13 @@ void signal_handler(int signum)
|
||||||
keep_running = 0;
|
keep_running = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get current wall time in seconds
|
||||||
|
static double get_wall_time(void)
|
||||||
|
{
|
||||||
|
struct timespec ts;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||||
|
return (double)ts.tv_sec + (double)ts.tv_nsec * 1.0e-9;
|
||||||
|
}
|
||||||
|
|
||||||
// Coin reconstruction from stored data
|
// Coin reconstruction from stored data
|
||||||
static void reconstruct_coin(u32_t *stored_data, u32_t coin[14])
|
static void reconstruct_coin(u32_t *stored_data, u32_t coin[14])
|
||||||
|
|
@ -38,7 +46,7 @@ static void reconstruct_coin(u32_t *stored_data, u32_t coin[14])
|
||||||
//
|
//
|
||||||
// Mine DETI coins using CUDA
|
// Mine DETI coins using CUDA
|
||||||
//
|
//
|
||||||
static void mine_coins_cuda(u64_t max_attempts)
|
static void mine_coins_cuda(u64_t max_attempts, double max_time)
|
||||||
{
|
{
|
||||||
cuda_data_t cd;
|
cuda_data_t cd;
|
||||||
u32_t *host_storage;
|
u32_t *host_storage;
|
||||||
|
|
@ -67,15 +75,35 @@ static void mine_coins_cuda(u64_t max_attempts)
|
||||||
printf("Grid: %u blocks × %u threads = %u total threads\n",
|
printf("Grid: %u blocks × %u threads = %u total threads\n",
|
||||||
cd.grid_dim_x, cd.block_dim_x, n_threads);
|
cd.grid_dim_x, cd.block_dim_x, n_threads);
|
||||||
printf("Kernel: %s\n", cd.kernel_name);
|
printf("Kernel: %s\n", cd.kernel_name);
|
||||||
|
|
||||||
|
if(max_attempts > 0 && max_time > 0)
|
||||||
|
printf("Will stop after %llu attempts OR %.2f seconds (whichever comes first)\n",
|
||||||
|
(unsigned long long)max_attempts, max_time);
|
||||||
|
else if(max_attempts > 0)
|
||||||
|
printf("Will stop after %llu attempts\n", (unsigned long long)max_attempts);
|
||||||
|
else if(max_time > 0)
|
||||||
|
printf("Will stop after %.2f seconds\n", max_time);
|
||||||
|
else
|
||||||
|
printf("Running indefinitely until Ctrl+C...\n");
|
||||||
|
|
||||||
printf("Press Ctrl+C to stop\n\n");
|
printf("Press Ctrl+C to stop\n\n");
|
||||||
|
|
||||||
u64_t base_nonce = 0;
|
u64_t base_nonce = 0;
|
||||||
u32_t attempts_per_thread = 1024 * 8; // Increased attempts per thread
|
u32_t attempts_per_thread = 1024 * 8; // Increased attempts per thread
|
||||||
|
|
||||||
|
double start_time = get_wall_time();
|
||||||
time_measurement();
|
time_measurement();
|
||||||
|
|
||||||
while(keep_running && (max_attempts == 0 || attempts < max_attempts))
|
while(keep_running)
|
||||||
{
|
{
|
||||||
|
// Check stopping conditions
|
||||||
|
if(max_attempts > 0 && attempts >= max_attempts)
|
||||||
|
break;
|
||||||
|
|
||||||
|
double elapsed = get_wall_time() - start_time;
|
||||||
|
if(max_time > 0 && elapsed >= max_time)
|
||||||
|
break;
|
||||||
|
|
||||||
// Initialize storage area
|
// Initialize storage area
|
||||||
host_storage[0] = 1u; // First unused index
|
host_storage[0] = 1u; // First unused index
|
||||||
|
|
||||||
|
|
@ -130,24 +158,55 @@ static void mine_coins_cuda(u64_t max_attempts)
|
||||||
printf("Coins found: %u\n", coins_found);
|
printf("Coins found: %u\n", coins_found);
|
||||||
printf("Kernel launches: %u\n", kernel_runs);
|
printf("Kernel launches: %u\n", kernel_runs);
|
||||||
|
|
||||||
|
|
||||||
// Save any remaining coins
|
// Save any remaining coins
|
||||||
save_coin(NULL);
|
save_coin(NULL);
|
||||||
|
|
||||||
terminate_cuda(&cd);
|
terminate_cuda(&cd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void print_usage(const char *prog_name)
|
||||||
|
{
|
||||||
|
printf("Usage: %s [OPTIONS]\n", prog_name);
|
||||||
|
printf("Options:\n");
|
||||||
|
printf(" -a <attempts> Maximum number of attempts\n");
|
||||||
|
printf(" -t <seconds> Maximum time in seconds\n");
|
||||||
|
printf(" -h Show this help message\n");
|
||||||
|
printf("\nExamples:\n");
|
||||||
|
printf(" %s -a 1000000000 # Run for 1B attempts\n", prog_name);
|
||||||
|
printf(" %s -t 60 # Run for 60 seconds\n", prog_name);
|
||||||
|
printf(" %s -a 1000000000 -t 60 # Stop at 1B attempts OR 60s (whichever first)\n", prog_name);
|
||||||
|
printf(" %s # Run indefinitely until Ctrl+C\n", prog_name);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
u64_t max_attempts = 0;
|
u64_t max_attempts = 0;
|
||||||
|
double max_time = 0;
|
||||||
|
int opt;
|
||||||
|
|
||||||
signal(SIGINT, signal_handler);
|
signal(SIGINT, signal_handler);
|
||||||
|
|
||||||
if(argc > 1)
|
// Parse command line options
|
||||||
max_attempts = strtoull(argv[1], NULL, 10);
|
while((opt = getopt(argc, argv, "a:t:h")) != -1)
|
||||||
|
{
|
||||||
|
switch(opt)
|
||||||
|
{
|
||||||
|
case 'a':
|
||||||
|
max_attempts = strtoull(optarg, NULL, 10);
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
max_time = atof(optarg);
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
print_usage(argv[0]);
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
print_usage(argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mine_coins_cuda(max_attempts);
|
mine_coins_cuda(max_attempts, max_time);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <getopt.h>
|
||||||
#include "aad_data_types.h"
|
#include "aad_data_types.h"
|
||||||
#include "aad_utilities.h"
|
#include "aad_utilities.h"
|
||||||
#include "aad_sha1_cpu.h"
|
#include "aad_sha1_cpu.h"
|
||||||
|
|
@ -43,7 +44,7 @@ static double get_wall_time(void)
|
||||||
//
|
//
|
||||||
// Mine DETI coins using OpenCL
|
// Mine DETI coins using OpenCL
|
||||||
//
|
//
|
||||||
static void mine_coins_ocl(u64_t max_attempts)
|
static void mine_coins_ocl(u64_t max_attempts, double max_time)
|
||||||
{
|
{
|
||||||
ocl_data_t od;
|
ocl_data_t od;
|
||||||
u32_t *host_storage;
|
u32_t *host_storage;
|
||||||
|
|
@ -74,6 +75,17 @@ static void mine_coins_ocl(u64_t max_attempts)
|
||||||
printf("Work groups: %zu × %zu = %u total work items\n",
|
printf("Work groups: %zu × %zu = %u total work items\n",
|
||||||
od.global_work_size / od.local_work_size, od.local_work_size, n_threads);
|
od.global_work_size / od.local_work_size, od.local_work_size, n_threads);
|
||||||
printf("Kernel: %s\n", od.kernel_name);
|
printf("Kernel: %s\n", od.kernel_name);
|
||||||
|
|
||||||
|
if(max_attempts > 0 && max_time > 0)
|
||||||
|
printf("Will stop after %llu attempts OR %.2f seconds (whichever comes first)\n",
|
||||||
|
(unsigned long long)max_attempts, max_time);
|
||||||
|
else if(max_attempts > 0)
|
||||||
|
printf("Will stop after %llu attempts\n", (unsigned long long)max_attempts);
|
||||||
|
else if(max_time > 0)
|
||||||
|
printf("Will stop after %.2f seconds\n", max_time);
|
||||||
|
else
|
||||||
|
printf("Running indefinitely until Ctrl+C...\n");
|
||||||
|
|
||||||
printf("Press Ctrl+C to stop\n\n");
|
printf("Press Ctrl+C to stop\n\n");
|
||||||
|
|
||||||
u32_t param1 = (u32_t)time(NULL);
|
u32_t param1 = (u32_t)time(NULL);
|
||||||
|
|
@ -81,8 +93,16 @@ static void mine_coins_ocl(u64_t max_attempts)
|
||||||
|
|
||||||
double start_time = get_wall_time();
|
double start_time = get_wall_time();
|
||||||
|
|
||||||
while(keep_running && (max_attempts == 0 || attempts < max_attempts))
|
while(keep_running)
|
||||||
{
|
{
|
||||||
|
// Check stopping conditions
|
||||||
|
if(max_attempts > 0 && attempts >= max_attempts)
|
||||||
|
break;
|
||||||
|
|
||||||
|
double elapsed = get_wall_time() - start_time;
|
||||||
|
if(max_time > 0 && elapsed >= max_time)
|
||||||
|
break;
|
||||||
|
|
||||||
// Initialize storage area
|
// Initialize storage area
|
||||||
host_storage[0] = 1u;
|
host_storage[0] = 1u;
|
||||||
|
|
||||||
|
|
@ -135,7 +155,7 @@ static void mine_coins_ocl(u64_t max_attempts)
|
||||||
// Print progress every 10 kernel launches
|
// Print progress every 10 kernel launches
|
||||||
if(kernel_runs % 10 == 0)
|
if(kernel_runs % 10 == 0)
|
||||||
{
|
{
|
||||||
double elapsed = get_wall_time() - start_time;
|
elapsed = get_wall_time() - start_time;
|
||||||
double rate = attempts / elapsed;
|
double rate = attempts / elapsed;
|
||||||
printf("Attempts: %llu, Rate: %.2f MH/s, Coins: %u, Kernels: %u, Elapsed: %.2fs\n",
|
printf("Attempts: %llu, Rate: %.2f MH/s, Coins: %u, Kernels: %u, Elapsed: %.2fs\n",
|
||||||
(unsigned long long)attempts, rate / 1e6, coins_found, kernel_runs, elapsed);
|
(unsigned long long)attempts, rate / 1e6, coins_found, kernel_runs, elapsed);
|
||||||
|
|
@ -157,16 +177,49 @@ static void mine_coins_ocl(u64_t max_attempts)
|
||||||
terminate_ocl(&od);
|
terminate_ocl(&od);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void print_usage(const char *prog_name)
|
||||||
|
{
|
||||||
|
printf("Usage: %s [OPTIONS]\n", prog_name);
|
||||||
|
printf("Options:\n");
|
||||||
|
printf(" -a <attempts> Maximum number of attempts\n");
|
||||||
|
printf(" -t <seconds> Maximum time in seconds\n");
|
||||||
|
printf(" -h Show this help message\n");
|
||||||
|
printf("\nExamples:\n");
|
||||||
|
printf(" %s -a 1000000000 # Run for 1B attempts\n", prog_name);
|
||||||
|
printf(" %s -t 60 # Run for 60 seconds\n", prog_name);
|
||||||
|
printf(" %s -a 1000000000 -t 60 # Stop at 1B attempts OR 60s (whichever first)\n", prog_name);
|
||||||
|
printf(" %s # Run indefinitely until Ctrl+C\n", prog_name);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
u64_t max_attempts = 0;
|
u64_t max_attempts = 0;
|
||||||
|
double max_time = 0;
|
||||||
|
int opt;
|
||||||
|
|
||||||
signal(SIGINT, signal_handler);
|
signal(SIGINT, signal_handler);
|
||||||
|
|
||||||
if(argc > 1)
|
// Parse command line options
|
||||||
max_attempts = strtoull(argv[1], NULL, 10);
|
while((opt = getopt(argc, argv, "a:t:h")) != -1)
|
||||||
|
{
|
||||||
|
switch(opt)
|
||||||
|
{
|
||||||
|
case 'a':
|
||||||
|
max_attempts = strtoull(optarg, NULL, 10);
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
max_time = atof(optarg);
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
print_usage(argv[0]);
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
print_usage(argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mine_coins_ocl(max_attempts);
|
mine_coins_ocl(max_attempts, max_time);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <getopt.h>
|
||||||
#include "aad_data_types.h"
|
#include "aad_data_types.h"
|
||||||
#include "aad_utilities.h"
|
#include "aad_utilities.h"
|
||||||
#include "aad_sha1_cpu.h"
|
#include "aad_sha1_cpu.h"
|
||||||
|
|
@ -129,7 +130,7 @@ static void extract_coins(u32_t *interleaved_data, u32_t coins[][14], int simd_w
|
||||||
// mine DETI coins using AVX (4-way SIMD)
|
// mine DETI coins using AVX (4-way SIMD)
|
||||||
//
|
//
|
||||||
__attribute__((unused))
|
__attribute__((unused))
|
||||||
static void mine_coins_avx(u64_t max_attempts)
|
static void mine_coins_avx(u64_t max_attempts, double max_time)
|
||||||
{
|
{
|
||||||
const int SIMD_WIDTH = 4;
|
const int SIMD_WIDTH = 4;
|
||||||
u32_t base_coin[14];
|
u32_t base_coin[14];
|
||||||
|
|
@ -160,12 +161,31 @@ static void mine_coins_avx(u64_t max_attempts)
|
||||||
((u08_t *)base_coin)[i ^ 3] = 'A' + (i - 12) % 26;
|
((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");
|
||||||
|
|
||||||
|
if(max_attempts > 0 && max_time > 0)
|
||||||
|
printf("Will stop after %llu attempts OR %.2f seconds (whichever comes first)\n",
|
||||||
|
(unsigned long long)max_attempts, max_time);
|
||||||
|
else if(max_attempts > 0)
|
||||||
|
printf("Will stop after %llu attempts\n", (unsigned long long)max_attempts);
|
||||||
|
else if(max_time > 0)
|
||||||
|
printf("Will stop after %.2f seconds\n", max_time);
|
||||||
|
else
|
||||||
|
printf("Running indefinitely until Ctrl+C...\n");
|
||||||
|
|
||||||
printf("Press Ctrl+C to stop\n\n");
|
printf("Press Ctrl+C to stop\n\n");
|
||||||
|
|
||||||
double start_time = get_wall_time();
|
double start_time = get_wall_time();
|
||||||
|
|
||||||
while(keep_running && (max_attempts == 0 || attempts < max_attempts))
|
while(keep_running)
|
||||||
{
|
{
|
||||||
|
// Check stopping conditions
|
||||||
|
if(max_attempts > 0 && attempts >= max_attempts)
|
||||||
|
break;
|
||||||
|
|
||||||
|
double elapsed = get_wall_time() - start_time;
|
||||||
|
if(max_time > 0 && elapsed >= max_time)
|
||||||
|
break;
|
||||||
|
|
||||||
// Prepare coins for this batch
|
// Prepare coins for this batch
|
||||||
prepare_coins(base_coin, interleaved_data, SIMD_WIDTH);
|
prepare_coins(base_coin, interleaved_data, SIMD_WIDTH);
|
||||||
|
|
||||||
|
|
@ -193,7 +213,7 @@ 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)
|
||||||
{
|
{
|
||||||
double elapsed = get_wall_time() - start_time;
|
elapsed = get_wall_time() - start_time;
|
||||||
double rate = attempts / elapsed;
|
double rate = attempts / elapsed;
|
||||||
printf("Attempts: %llu, Rate: %.2f MH/s, Coins: %u, Elapsed: %.2fs\n",
|
printf("Attempts: %llu, Rate: %.2f MH/s, Coins: %u, Elapsed: %.2fs\n",
|
||||||
(unsigned long long)attempts, rate / 1e6, coins_found, elapsed);
|
(unsigned long long)attempts, rate / 1e6, coins_found, elapsed);
|
||||||
|
|
@ -217,7 +237,7 @@ static void mine_coins_avx(u64_t max_attempts)
|
||||||
// mine DETI coins using AVX2 (8-way SIMD)
|
// mine DETI coins using AVX2 (8-way SIMD)
|
||||||
//
|
//
|
||||||
__attribute__((unused))
|
__attribute__((unused))
|
||||||
static void mine_coins_avx2(u64_t max_attempts)
|
static void mine_coins_avx2(u64_t max_attempts, double max_time)
|
||||||
{
|
{
|
||||||
const int SIMD_WIDTH = 8;
|
const int SIMD_WIDTH = 8;
|
||||||
u32_t base_coin[14];
|
u32_t base_coin[14];
|
||||||
|
|
@ -248,12 +268,31 @@ static void mine_coins_avx2(u64_t max_attempts)
|
||||||
((u08_t *)base_coin)[i ^ 3] = 'A' + (i - 12) % 26;
|
((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");
|
||||||
|
|
||||||
|
if(max_attempts > 0 && max_time > 0)
|
||||||
|
printf("Will stop after %llu attempts OR %.2f seconds (whichever comes first)\n",
|
||||||
|
(unsigned long long)max_attempts, max_time);
|
||||||
|
else if(max_attempts > 0)
|
||||||
|
printf("Will stop after %llu attempts\n", (unsigned long long)max_attempts);
|
||||||
|
else if(max_time > 0)
|
||||||
|
printf("Will stop after %.2f seconds\n", max_time);
|
||||||
|
else
|
||||||
|
printf("Running indefinitely until Ctrl+C...\n");
|
||||||
|
|
||||||
printf("Press Ctrl+C to stop\n\n");
|
printf("Press Ctrl+C to stop\n\n");
|
||||||
|
|
||||||
double start_time = get_wall_time();
|
double start_time = get_wall_time();
|
||||||
|
|
||||||
while(keep_running && (max_attempts == 0 || attempts < max_attempts))
|
while(keep_running)
|
||||||
{
|
{
|
||||||
|
// Check stopping conditions
|
||||||
|
if(max_attempts > 0 && attempts >= max_attempts)
|
||||||
|
break;
|
||||||
|
|
||||||
|
double elapsed = get_wall_time() - start_time;
|
||||||
|
if(max_time > 0 && elapsed >= max_time)
|
||||||
|
break;
|
||||||
|
|
||||||
prepare_coins(base_coin, interleaved_data, SIMD_WIDTH);
|
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;
|
||||||
|
|
@ -276,7 +315,7 @@ static void mine_coins_avx2(u64_t max_attempts)
|
||||||
|
|
||||||
if(attempts % 1000000 < SIMD_WIDTH)
|
if(attempts % 1000000 < SIMD_WIDTH)
|
||||||
{
|
{
|
||||||
double elapsed = get_wall_time() - start_time;
|
elapsed = get_wall_time() - start_time;
|
||||||
double rate = attempts / elapsed;
|
double rate = attempts / elapsed;
|
||||||
printf("Attempts: %llu, Rate: %.2f MH/s, Coins: %u, Elapsed: %.2fs\n",
|
printf("Attempts: %llu, Rate: %.2f MH/s, Coins: %u, Elapsed: %.2fs\n",
|
||||||
(unsigned long long)attempts, rate / 1e6, coins_found, elapsed);
|
(unsigned long long)attempts, rate / 1e6, coins_found, elapsed);
|
||||||
|
|
@ -301,14 +340,26 @@ static void mine_coins_avx2(u64_t max_attempts)
|
||||||
// mine DETI coins using AVX2 (8-way SIMD) + OpenMP
|
// mine DETI coins using AVX2 (8-way SIMD) + OpenMP
|
||||||
//
|
//
|
||||||
__attribute__((unused))
|
__attribute__((unused))
|
||||||
static void mine_coins_avx2_omp(u64_t max_attempts)
|
static void mine_coins_avx2_omp(u64_t max_attempts, double max_time)
|
||||||
{
|
{
|
||||||
const int SIMD_WIDTH = 8;
|
const int SIMD_WIDTH = 8;
|
||||||
int num_threads = omp_get_max_threads();
|
int num_threads = omp_get_max_threads();
|
||||||
u64_t attempts = 0;
|
u64_t attempts = 0;
|
||||||
u32_t coins_found = 0;
|
u32_t coins_found = 0;
|
||||||
|
u64_t last_reported_attempts = 0;
|
||||||
|
|
||||||
printf("Mining DETI coins using AVX2 (8-way SIMD) + OpenMP (%d threads)...\n", num_threads);
|
printf("Mining DETI coins using AVX2 (8-way SIMD) + OpenMP (%d threads)...\n", num_threads);
|
||||||
|
|
||||||
|
if(max_attempts > 0 && max_time > 0)
|
||||||
|
printf("Will stop after %llu attempts OR %.2f seconds (whichever comes first)\n",
|
||||||
|
(unsigned long long)max_attempts, max_time);
|
||||||
|
else if(max_attempts > 0)
|
||||||
|
printf("Will stop after %llu attempts\n", (unsigned long long)max_attempts);
|
||||||
|
else if(max_time > 0)
|
||||||
|
printf("Will stop after %.2f seconds\n", max_time);
|
||||||
|
else
|
||||||
|
printf("Running indefinitely until Ctrl+C...\n");
|
||||||
|
|
||||||
printf("Press Ctrl+C to stop\n\n");
|
printf("Press Ctrl+C to stop\n\n");
|
||||||
|
|
||||||
double start_time = get_wall_time();
|
double start_time = get_wall_time();
|
||||||
|
|
@ -342,8 +393,16 @@ static void mine_coins_avx2_omp(u64_t max_attempts)
|
||||||
for(int i = 12; i < 54; i++)
|
for(int i = 12; i < 54; i++)
|
||||||
((u08_t *)base_coin)[i ^ 3] = 'A' + ((i - 12 + thread_id * SIMD_WIDTH) % 26);
|
((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))
|
while(keep_running)
|
||||||
{
|
{
|
||||||
|
// Check stopping conditions
|
||||||
|
if(max_attempts > 0 && attempts >= max_attempts)
|
||||||
|
break;
|
||||||
|
|
||||||
|
double elapsed_time = get_wall_time() - start_time;
|
||||||
|
if(max_time > 0 && elapsed_time >= max_time)
|
||||||
|
break;
|
||||||
|
|
||||||
prepare_coins(base_coin, interleaved_data, SIMD_WIDTH);
|
prepare_coins(base_coin, interleaved_data, SIMD_WIDTH);
|
||||||
sha1_avx2((v8si *)interleaved_data, (v8si *)interleaved_hash);
|
sha1_avx2((v8si *)interleaved_data, (v8si *)interleaved_hash);
|
||||||
thread_attempts += SIMD_WIDTH;
|
thread_attempts += SIMD_WIDTH;
|
||||||
|
|
@ -368,15 +427,26 @@ static void mine_coins_avx2_omp(u64_t max_attempts)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print progress every 1M attempts (per thread)
|
// Print progress every 1M attempts (only from one thread)
|
||||||
if(thread_attempts % 1000000 < SIMD_WIDTH)
|
// Periodically update the shared counter and report
|
||||||
|
if(thread_attempts % 100000 < SIMD_WIDTH)
|
||||||
{
|
{
|
||||||
#pragma omp critical
|
#pragma omp atomic
|
||||||
|
attempts += thread_attempts;
|
||||||
|
thread_attempts = 0;
|
||||||
|
|
||||||
|
#pragma omp barrier
|
||||||
|
|
||||||
|
#pragma omp master
|
||||||
|
{
|
||||||
|
if(attempts - last_reported_attempts >= 1000000)
|
||||||
{
|
{
|
||||||
double elapsed = get_wall_time() - start_time;
|
double elapsed = get_wall_time() - start_time;
|
||||||
double rate = (attempts + thread_attempts) / elapsed;
|
double rate = attempts / elapsed;
|
||||||
printf("Attempts: %llu, Rate: %.2f MH/s, Coins: %u, Elapsed: %.2fs\n",
|
printf("Attempts: %llu, Rate: %.2f MH/s, Coins: %u, Elapsed: %.2fs\n",
|
||||||
(unsigned long long)(attempts + thread_attempts), rate / 1e6, coins_found, elapsed);
|
(unsigned long long)attempts, rate / 1e6, coins_found, elapsed);
|
||||||
|
last_reported_attempts = attempts;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -397,30 +467,123 @@ static void mine_coins_avx2_omp(u64_t max_attempts)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void print_usage(const char *prog_name)
|
||||||
|
{
|
||||||
|
printf("Usage: %s [OPTIONS]\n", prog_name);
|
||||||
|
printf("Options:\n");
|
||||||
|
printf(" -a <attempts> Maximum number of attempts\n");
|
||||||
|
printf(" -t <seconds> Maximum time in seconds\n");
|
||||||
|
printf(" --avx Use AVX (4-way SIMD)\n");
|
||||||
|
printf(" --avx2 Use AVX2 (8-way SIMD)\n");
|
||||||
|
printf(" --omp Use AVX2 + OpenMP (multi-threaded)\n");
|
||||||
|
printf(" -h Show this help message\n");
|
||||||
|
printf("\nNote: Only one SIMD mode (--avx, --avx2, --omp) can be used at a time.\n");
|
||||||
|
printf(" If no SIMD mode is specified, the program will auto-detect.\n");
|
||||||
|
printf("\nExamples:\n");
|
||||||
|
printf(" %s --avx2 -a 1000000 # AVX2 for 1M attempts\n", prog_name);
|
||||||
|
printf(" %s --omp -t 60 # AVX2+OpenMP for 60 seconds\n", prog_name);
|
||||||
|
printf(" %s --avx -a 1000000 -t 60 # AVX, stop at 1M or 60s\n", prog_name);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
u64_t max_attempts = 0;
|
u64_t max_attempts = 0;
|
||||||
|
double max_time = 0;
|
||||||
|
int use_avx = 0;
|
||||||
|
int use_avx2 = 0;
|
||||||
|
int use_omp = 0;
|
||||||
|
int opt;
|
||||||
|
|
||||||
signal(SIGINT, signal_handler);
|
signal(SIGINT, signal_handler);
|
||||||
|
|
||||||
if(argc > 1)
|
// Define long options
|
||||||
max_attempts = strtoull(argv[1], NULL, 10);
|
static struct option long_options[] = {
|
||||||
|
{"avx", no_argument, 0, 'x'},
|
||||||
|
{"avx2", no_argument, 0, 'y'},
|
||||||
|
{"omp", no_argument, 0, 'o'},
|
||||||
|
{0, 0, 0, 0}
|
||||||
|
};
|
||||||
|
|
||||||
#if defined(__AVX2__)
|
// Parse command line options
|
||||||
if(argc > 2 && strcmp(argv[2], "omp") == 0) {
|
int option_index = 0;
|
||||||
printf("Using AVX2 + OpenMP implementation\n");
|
while((opt = getopt_long(argc, argv, "a:t:h", long_options, &option_index)) != -1)
|
||||||
mine_coins_avx2_omp(max_attempts);
|
{
|
||||||
} else {
|
switch(opt)
|
||||||
printf("Using AVX2 implementation\n");
|
{
|
||||||
mine_coins_avx2(max_attempts);
|
case 'a':
|
||||||
|
max_attempts = strtoull(optarg, NULL, 10);
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
max_time = atof(optarg);
|
||||||
|
break;
|
||||||
|
case 'x':
|
||||||
|
use_avx = 1;
|
||||||
|
break;
|
||||||
|
case 'y':
|
||||||
|
use_avx2 = 1;
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
use_omp = 1;
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
print_usage(argv[0]);
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
print_usage(argv[0]);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
#elif defined(__AVX__)
|
}
|
||||||
printf("Using AVX implementation\n");
|
|
||||||
mine_coins_avx(max_attempts);
|
// Check for conflicting SIMD modes
|
||||||
|
int simd_flags = use_avx + use_avx2 + use_omp;
|
||||||
|
if(simd_flags > 1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error: Only one SIMD mode (--avx, --avx2, --omp) can be specified.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute based on selected mode
|
||||||
|
if(use_omp)
|
||||||
|
{
|
||||||
|
#if defined(__AVX2__)
|
||||||
|
mine_coins_avx2_omp(max_attempts, max_time);
|
||||||
#else
|
#else
|
||||||
printf("Error: No SIMD instruction set available. Compile with -mavx or -mavx2\n");
|
fprintf(stderr, "Error: OpenMP mode requires AVX2 support. Compile with -mavx2 -fopenmp\n");
|
||||||
return 1;
|
return 1;
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
else if(use_avx2)
|
||||||
|
{
|
||||||
|
#if defined(__AVX2__)
|
||||||
|
mine_coins_avx2(max_attempts, max_time);
|
||||||
|
#else
|
||||||
|
fprintf(stderr, "Error: AVX2 not available. Compile with -mavx2\n");
|
||||||
|
return 1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else if(use_avx)
|
||||||
|
{
|
||||||
|
#if defined(__AVX__)
|
||||||
|
mine_coins_avx(max_attempts, max_time);
|
||||||
|
#else
|
||||||
|
fprintf(stderr, "Error: AVX not available. Compile with -mavx\n");
|
||||||
|
return 1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Auto-detect: use best available
|
||||||
|
#if defined(__AVX2__)
|
||||||
|
printf("Auto-detecting: Using AVX2 implementation\n");
|
||||||
|
mine_coins_avx2(max_attempts, max_time);
|
||||||
|
#elif defined(__AVX__)
|
||||||
|
printf("Auto-detecting: Using AVX implementation\n");
|
||||||
|
mine_coins_avx(max_attempts, max_time);
|
||||||
|
#else
|
||||||
|
fprintf(stderr, "Error: No SIMD instruction set available. Compile with -mavx or -mavx2\n");
|
||||||
|
return 1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue