From 7158f9f9ed9ead4dfee4fab3a022492cfd798830 Mon Sep 17 00:00:00 2001 From: Znort 987 Date: Fri, 12 Aug 2011 13:38:18 +0200 Subject: [PATCH] Add automated benchmark of the CPU hashers The --algo switch now accepts the "auto" argument. When "auto" is passed to --algo, cgminer starts by benchmarking all the CPU algorithms it nows about and picks the fastest. This is useful for benchmarking, but also for folks who run cgminer on a large number of heterogeneous computers because it saves them from having to configure each instance optimally. Caveat emptor: depending on the platform, some algorithms will fail with "illegal instruction" (e.g. via padlock code on non via platforms, or SSE4 code on non SSE4 platforms). To protect against this, cgminer runs the benchmarks in a child process. The crash, if any occurs in the child, and the parent marks this algo as "fails" and continues benchmarking the next algorithm. Unfortunately, this safeguard is only implemented for Linux because I have no clue how to do this on win32 (nor access to a win32 box). --- main.c | 293 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 291 insertions(+), 2 deletions(-) diff --git a/main.c b/main.c index ed06c096..e4ee84e3 100644 --- a/main.c +++ b/main.c @@ -36,6 +36,12 @@ #include "findnonce.h" #include "ocl.h" +#if defined(__linux) + #include + #include + #include +#endif + #define PROGRAM_NAME "cgminer" #define DEF_RPC_URL "http://127.0.0.1:8332/" #define DEF_RPC_USERNAME "rpcuser" @@ -118,6 +124,8 @@ struct strategies { { "Load Balance" }, }; +static size_t max_name_len = 0; +static char *name_spaces_pad = NULL; static const char *algo_names[] = { [ALGO_C] = "c", #ifdef WANT_SSE2_4WAY @@ -138,6 +146,27 @@ static const char *algo_names[] = { #endif }; +typedef void (*sha256_func)(); +static const sha256_func sha256_funcs[] = { + [ALGO_C] = (sha256_func)scanhash_c, +#ifdef WANT_SSE2_4WAY + [ALGO_4WAY] = (sha256_func)ScanHash_4WaySSE2, +#endif +#ifdef WANT_VIA_PADLOCK + [ALGO_VIA] = (sha256_func)scanhash_via, +#endif + [ALGO_CRYPTOPP] = (sha256_func)scanhash_cryptopp, +#ifdef WANT_CRYPTOPP_ASM32 + [ALGO_CRYPTOPP_ASM32] = (sha256_func)scanhash_asm32, +#endif +#ifdef WANT_X8664_SSE2 + [ALGO_SSE2_64] = (sha256_func)scanhash_sse2_64, +#endif +#ifdef WANT_X8664_SSE4 + [ALGO_SSE4_64] = (sha256_func)scanhash_sse4_64 +#endif +}; + bool opt_debug = false; bool opt_protocol = false; bool want_longpoll = true; @@ -329,11 +358,268 @@ static struct pool *current_pool(void) return pool; } +static double bench_algo_stage3( + enum sha256_algos algo +) +{ + static uint8_t some_block[] = { + 0x00, 0x00, 0x00, 0x01, 0x20, 0x00, 0xD8, 0x07, 0x17, 0xC9, 0x13, 0x6F, 0xDC, 0xBE, 0xDE, 0xB7, + 0xB2, 0x14, 0xEF, 0xD1, 0x72, 0x7F, 0xA3, 0x72, 0xB2, 0x5D, 0x88, 0xF0, 0x00, 0x00, 0x05, 0xAA, + 0x00, 0x00, 0x00, 0x00, 0x92, 0x8B, 0x4C, 0x77, 0xF5, 0xB2, 0xE6, 0x56, 0x96, 0x27, 0xE0, 0x66, + 0x3C, 0x5B, 0xDD, 0xDC, 0x88, 0x6A, 0x7D, 0x7C, 0x7B, 0x8C, 0xE4, 0x92, 0x38, 0x92, 0x58, 0x2E, + 0x18, 0x4D, 0x95, 0x9E, 0x4E, 0x44, 0xF1, 0x5F, 0x1A, 0x08, 0xE1, 0xE5, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x86, 0x7E, 0x3A, 0xAF, 0x37, 0x83, 0xAF, 0xA0, 0xB5, 0x33, 0x2C, 0x28, 0xED, 0xA9, 0x89, 0x3E, + 0x0A, 0xB6, 0x46, 0x81, 0xC2, 0x71, 0x4F, 0x34, 0x5A, 0x74, 0x89, 0x0E, 0x2B, 0x04, 0xB3, 0x16, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0xF6, 0x09, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x55, 0xF1, 0x44, 0x4E, 0x00, 0x00, 0x00, 0x00, 0x79, 0x63, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + struct work work __attribute__((aligned(128))); + assert(sizeof(work) == sizeof(some_block)); + memcpy(&work, &some_block, sizeof(work)); + + struct work_restart dummy; + work_restart = &dummy; + + struct timeval end; + struct timeval start; + uint64_t hashes_done = 0; + uint32_t max_nonce = (1<<21); + + gettimeofday(&start, 0); + #ifdef WANT_VIA_PADLOCK + if (ALGO_VIA==algo) { + (void)scanhash_via( + 0, + work.data, + work.target, + max_nonce, + &hashes_done, + work.blk.nonce + ); + } else + #endif + { + sha256_func func = sha256_funcs[algo]; + (*func)( + 0, + work.midstate, + work.data + 64, + work.hash1, + work.hash, + work.target, + max_nonce, + &hashes_done, + work.blk.nonce + ); + } + gettimeofday(&end, 0); + work_restart = NULL; + + uint64_t usec_end = ((uint64_t)end.tv_sec)*1000*1000 + end.tv_usec; + uint64_t usec_start = ((uint64_t)start.tv_sec)*1000*1000 + start.tv_usec; + uint64_t usec_elapsed = usec_end - usec_start; + + double rate = -1.0; + if (0