From e0dc6649e10b9a78a7c12efce86a1d4bb537c00a Mon Sep 17 00:00:00 2001 From: pooler Date: Tue, 17 Jan 2012 00:38:06 +0100 Subject: [PATCH] Version 2.0 - Test the whole hash instead of just looking at the high 32 bits - Set idle priority on Windows - Fix parameters -u and -p, and add short options -o and -O - Fix example JSON configuration file --- AUTHORS | 2 - NEWS | 13 ++++ README | 7 +- compat.h | 3 +- configure.ac | 2 +- cpu-miner.c | 45 ++++++------ example-cfg.json | 4 +- scrypt-x86.S | 173 +++++++++++------------------------------------ scrypt.c | 19 +++++- 9 files changed, 102 insertions(+), 166 deletions(-) diff --git a/AUTHORS b/AUTHORS index 4bc52e1..984b32c 100644 --- a/AUTHORS +++ b/AUTHORS @@ -2,6 +2,4 @@ Jeff Garzik ArtForz - Lolcust - pooler diff --git a/NEWS b/NEWS index 1ab5040..1cb04f9 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,16 @@ +Version 2.0 - Jan 16, 2012 + +- Change default port to 9332 for Litecoin and remove default credentials +- Add 'scrypt' as the default algorithm and remove other algorithms (ArtForz) +- Optimize scrypt for x86 and x86-64 +- Test the whole hash instead of just looking at the high 32 bits +- Add configurable timeout, with a default of 180 seconds +- Add share summary output (inlikeflynn) +- Fix priority and CPU count detection on Windows +- Fix parameters -u and -p, and add short options -o and -O + +Version 1.0.2 - Jun 13, 2011 + - Linux x86_64 optimisations - Con Kolivas - Optimise for x86_64 by default by using sse2_64 algo - Detects CPUs and sets number of threads accordingly diff --git a/README b/README index 3e999d3..9ad2b67 100644 --- a/README +++ b/README @@ -1,4 +1,5 @@ -This is a multi-threaded CPU miner for Litecoin, fork of Jeff Garzik's reference cpuminer. +This is a multi-threaded CPU miner for Litecoin, fork of Jeff Garzik's +reference cpuminer. License: GPLv2. See COPYING for details. @@ -10,13 +11,13 @@ Dependencies: Basic *nix build instructions: ./autogen.sh # only needed if building from git repo - CFLAGS="-O3 -Wall -msse2" ./configure + ./configure CFLAGS="-O3" make Basic WIN32 build instructions (on Fedora 13; requires mingw32): ./autogen.sh # only needed if building from git repo rm -f mingw32-config.cache - MINGW32_CFLAGS="-O3 -Wall -msse2" mingw32-configure + MINGW32_CFLAGS="-O3" mingw32-configure make ./mknsis.sh diff --git a/compat.h b/compat.h index 1fdf6d1..3eba4a5 100644 --- a/compat.h +++ b/compat.h @@ -16,8 +16,7 @@ enum { static inline int setpriority(int which, int who, int prio) { - /* FIXME - actually do something */ - return 0; + return -!SetPriorityClass(GetCurrentProcess(), IDLE_PRIORITY_CLASS); } #endif /* WIN32 */ diff --git a/configure.ac b/configure.ac index c41e555..c6886cb 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([cpuminer], [1.0.2]) +AC_INIT([cpuminer], [2.0]) AC_PREREQ(2.52) AC_CANONICAL_SYSTEM diff --git a/cpu-miner.c b/cpu-miner.c index 9d2ae91..1ebab72 100644 --- a/cpu-miner.c +++ b/cpu-miner.c @@ -23,6 +23,7 @@ #include #else #include +#include #endif #include #include @@ -126,35 +127,33 @@ static struct option_help options_help[] = { "(-h) Display this help text" }, { "config FILE", - "(-c FILE) JSON-format configuration file (default: none)\n" - "See example-cfg.json for an example configuration." }, + "(-c FILE) Load a JSON-format configuration file" }, { "algo XXX", - "(-a XXX) Only scrypt (e.g. --algo scrypt) is supported" }, + "(-a XXX) Specify the algorithm to use (default: scrypt)" }, { "quiet", - "(-q) Disable per-thread hashmeter output (default: off)" }, + "(-q) Disable per-thread hashmeter output" }, { "debug", - "(-D) Enable debug output (default: off)" }, + "(-D) Enable debug output" }, { "no-longpoll", - "Disable X-Long-Polling support (default: enabled)" }, + "Disable X-Long-Polling support" }, { "protocol-dump", - "(-P) Verbose dump of protocol-level activities (default: off)" }, + "(-P) Verbose dump of protocol-level activities" }, { "retries N", "(-r N) Number of times to retry if JSON-RPC call fails\n" "\t(default: retry indefinitely)" }, { "retry-pause N", - "(-R N) Number of seconds to pause between retries\n" - "\t(default: 30)" }, + "(-R N) Number of seconds to pause between retries (default: 30)" }, { "scantime N", - "(-s N) Upper bound on time spent scanning current work,\n" - "\tin seconds. (default: 5)" }, + "(-s N) Upper bound on time spent scanning current work, in seconds\n" + "\t(default: 5)" }, { "timeout N", "(-T N) Connection timeout, in seconds (default: 180)" }, @@ -168,11 +167,11 @@ static struct option_help options_help[] = { "(-t N) Number of miner threads (default: number of processors)" }, { "url URL", - "URL for JSON-RPC server " + "(-o URL) URL for JSON-RPC server " "(default: " DEF_RPC_URL ")" }, { "userpass USERNAME:PASSWORD", - "Username:Password pair for JSON-RPC server" }, + "(-O USERNAME:PASSWORD) Username:Password pair for JSON-RPC server" }, { "user USERNAME", "(-u USERNAME) Username for JSON-RPC server" }, @@ -198,9 +197,9 @@ static struct option options[] = { #ifdef HAVE_SYSLOG_H { "syslog", 0, NULL, 1004 }, #endif - { "url", 1, NULL, 1001 }, + { "url", 1, NULL, 'o' }, { "user", 1, NULL, 'u' }, - { "userpass", 1, NULL, 1002 }, + { "userpass", 1, NULL, 'O' }, { } }; @@ -784,7 +783,7 @@ static void parse_arg (int key, char *arg) free(rpc_user); rpc_user = strdup(arg); break; - case 1001: /* --url */ + case 'o': /* --url */ if (strncmp(arg, "http://", 7) && strncmp(arg, "https://", 8)) show_usage(); @@ -792,7 +791,7 @@ static void parse_arg (int key, char *arg) free(rpc_url); rpc_url = strdup(arg); break; - case 1002: /* --userpass */ + case 'O': /* --userpass */ if (!strchr(arg, ':')) show_usage(); @@ -813,9 +812,17 @@ static void parse_arg (int key, char *arg) SYSTEM_INFO sysinfo; GetSystemInfo(&sysinfo); num_processors = sysinfo.dwNumberOfProcessors; -#else +#elif defined(_SC_NPROCESSORS_ONLN) num_processors = sysconf(_SC_NPROCESSORS_ONLN); +#elif defined(HW_NCPU) + int req[] = { CTL_HW, HW_NCPU }; + size_t len = sizeof(num_processors); + v = sysctl(req, 2, &num_processors, &len, NULL, 0); +#else + num_processors = 1; #endif + if (num_processors < 1) + num_processors = 1; if (!opt_n_threads) opt_n_threads = num_processors; } @@ -857,7 +864,7 @@ static void parse_cmdline(int argc, char *argv[]) int key; while (1) { - key = getopt_long(argc, argv, "a:c:qDPr:s:T:t:h?", options, NULL); + key = getopt_long(argc, argv, "hc:a:qDPr:s:T:t:o:O:u:p:", options, NULL); if (key < 0) break; diff --git a/example-cfg.json b/example-cfg.json index 8bda9db..228a66d 100644 --- a/example-cfg.json +++ b/example-cfg.json @@ -2,11 +2,11 @@ "_comment1" : "Any long-format command line argument ", "_comment2" : "may be used in this JSON configuration file", - "url" : "http://127.0.0.1:8332", + "url" : "http://127.0.0.1:9332/", "user" : "rpcuser", "pass" : "rpcpass", - "algo" : "sse2_64", + "algo" : "scrypt", "threads" : "4", "quiet" : true diff --git a/scrypt-x86.S b/scrypt-x86.S index c0144b9..62e77fa 100644 --- a/scrypt-x86.S +++ b/scrypt-x86.S @@ -27,6 +27,41 @@ #endif #if defined(__i386__) + +.macro scrypt_shuffle src, so, dest, do + movl \so+60(\src), %eax + movl \so+44(\src), %ebx + movl \so+28(\src), %ecx + movl \so+12(\src), %edx + movl %eax, \do+12(\dest) + movl %ebx, \do+28(\dest) + movl %ecx, \do+44(\dest) + movl %edx, \do+60(\dest) + movl \so+40(\src), %eax + movl \so+8(\src), %ebx + movl \so+48(\src), %ecx + movl \so+16(\src), %edx + movl %eax, \do+8(\dest) + movl %ebx, \do+40(\dest) + movl %ecx, \do+16(\dest) + movl %edx, \do+48(\dest) + movl \so+20(\src), %eax + movl \so+4(\src), %ebx + movl \so+52(\src), %ecx + movl \so+36(\src), %edx + movl %eax, \do+4(\dest) + movl %ebx, \do+20(\dest) + movl %ecx, \do+36(\dest) + movl %edx, \do+52(\dest) + movl \so+0(\src), %eax + movl \so+24(\src), %ebx + movl \so+32(\src), %ecx + movl \so+56(\src), %edx + movl %eax, \do+0(\dest) + movl %ebx, \do+24(\dest) + movl %ecx, \do+32(\dest) + movl %edx, \do+56(\dest) +.endm .macro gen_salsa8_core_quadround movl 52(%esp), %ecx @@ -648,73 +683,8 @@ xmm_scrypt_core: subl $128, %esp andl $-16, %esp - # shuffle 1st block to (%esp) - movl 60(%edi), %edx - movl 44(%edi), %ecx - movl 28(%edi), %ebx - movl 12(%edi), %eax - movl %edx, 12(%esp) - movl %ecx, 28(%esp) - movl %ebx, 44(%esp) - movl %eax, 60(%esp) - movl 40(%edi), %ecx - movl 24(%edi), %ebx - movl 8(%edi), %eax - movl 56(%edi), %edx - movl %ecx, 8(%esp) - movl %ebx, 24(%esp) - movl %eax, 40(%esp) - movl %edx, 56(%esp) - movl 20(%edi), %ebx - movl 4(%edi), %eax - movl 52(%edi), %edx - movl 36(%edi), %ecx - movl %ebx, 4(%esp) - movl %eax, 20(%esp) - movl %edx, 36(%esp) - movl %ecx, 52(%esp) - movl 0(%edi), %eax - movl 48(%edi), %edx - movl 32(%edi), %ecx - movl 16(%edi), %ebx - movl %eax, 0(%esp) - movl %edx, 16(%esp) - movl %ecx, 32(%esp) - movl %ebx, 48(%esp) - - # shuffle 2nd block to 64(%esp) - movl 124(%edi), %edx - movl 108(%edi), %ecx - movl 92(%edi), %ebx - movl 76(%edi), %eax - movl %edx, 76(%esp) - movl %ecx, 92(%esp) - movl %ebx, 108(%esp) - movl %eax, 124(%esp) - movl 104(%edi), %ecx - movl 88(%edi), %ebx - movl 72(%edi), %eax - movl 120(%edi), %edx - movl %ecx, 72(%esp) - movl %ebx, 88(%esp) - movl %eax, 104(%esp) - movl %edx, 120(%esp) - movl 84(%edi), %ebx - movl 68(%edi), %eax - movl 116(%edi), %edx - movl 100(%edi), %ecx - movl %ebx, 68(%esp) - movl %eax, 84(%esp) - movl %edx, 100(%esp) - movl %ecx, 116(%esp) - movl 64(%edi), %eax - movl 112(%edi), %edx - movl 96(%edi), %ecx - movl 80(%edi), %ebx - movl %eax, 64(%esp) - movl %edx, 80(%esp) - movl %ecx, 96(%esp) - movl %ebx, 112(%esp) + scrypt_shuffle %edi, 0, %esp, 0 + scrypt_shuffle %edi, 64, %esp, 64 movdqa 96(%esp), %xmm6 movdqa 112(%esp), %xmm7 @@ -834,73 +804,8 @@ xmm_scrypt_core_loop2: movdqa %xmm6, 96(%esp) movdqa %xmm7, 112(%esp) - # re-shuffle 1st block back - movl 60(%esp), %edx - movl 44(%esp), %ecx - movl 28(%esp), %ebx - movl 12(%esp), %eax - movl %edx, 12(%edi) - movl %ecx, 28(%edi) - movl %ebx, 44(%edi) - movl %eax, 60(%edi) - movl 40(%esp), %ecx - movl 24(%esp), %ebx - movl 8(%esp), %eax - movl 56(%esp), %edx - movl %ecx, 8(%edi) - movl %ebx, 24(%edi) - movl %eax, 40(%edi) - movl %edx, 56(%edi) - movl 20(%esp), %ebx - movl 4(%esp), %eax - movl 52(%esp), %edx - movl 36(%esp), %ecx - movl %ebx, 4(%edi) - movl %eax, 20(%edi) - movl %edx, 36(%edi) - movl %ecx, 52(%edi) - movl 0(%esp), %eax - movl 48(%esp), %edx - movl 32(%esp), %ecx - movl 16(%esp), %ebx - movl %eax, 0(%edi) - movl %edx, 16(%edi) - movl %ecx, 32(%edi) - movl %ebx, 48(%edi) - - # re-shuffle 2nd block back - movl 124(%esp), %edx - movl 108(%esp), %ecx - movl 92(%esp), %ebx - movl 76(%esp), %eax - movl %edx, 76(%edi) - movl %ecx, 92(%edi) - movl %ebx, 108(%edi) - movl %eax, 124(%edi) - movl 104(%esp), %ecx - movl 88(%esp), %ebx - movl 72(%esp), %eax - movl 120(%esp), %edx - movl %ecx, 72(%edi) - movl %ebx, 88(%edi) - movl %eax, 104(%edi) - movl %edx, 120(%edi) - movl 84(%esp), %ebx - movl 68(%esp), %eax - movl 116(%esp), %edx - movl 100(%esp), %ecx - movl %ebx, 68(%edi) - movl %eax, 84(%edi) - movl %edx, 100(%edi) - movl %ecx, 116(%edi) - movl 64(%esp), %eax - movl 112(%esp), %edx - movl 96(%esp), %ecx - movl 80(%esp), %ebx - movl %eax, 64(%edi) - movl %edx, 80(%edi) - movl %ecx, 96(%edi) - movl %ebx, 112(%edi) + scrypt_shuffle %esp, 0, %edi, 0 + scrypt_shuffle %esp, 64, %edi, 64 movl %ebp, %esp popl %esi diff --git a/scrypt.c b/scrypt.c index 304822c..6ea4b3e 100644 --- a/scrypt.c +++ b/scrypt.c @@ -497,6 +497,19 @@ static void scrypt_1024_1_1_256_sp_3way(const uint32_t *input1, const uint32_t * #endif +static int test_hash(const uint32_t *hash, const uint32_t *target) +{ + int i; + for (i = 7; i >= 0; i--) { + uint32_t t = le32dec(&target[i]); + if (hash[i] > t) + return 0; + if (hash[i] < t) + return 1; + } + return 1; +} + int scanhash_scrypt(int thr_id, unsigned char *pdata, unsigned char *scratchbuf, const unsigned char *ptarget, uint32_t max_nonce, unsigned long *hashes_done) @@ -529,7 +542,7 @@ int scanhash_scrypt(int thr_id, unsigned char *pdata, unsigned char *scratchbuf, if (throughput >= 3 && n < max_nonce) { data3[19] = n++; scrypt_1024_1_1_256_sp_3way(data, data2, data3, hash, hash2, hash3, scratchbuf); - if (hash3[7] <= Htarg) { + if (hash3[7] < Htarg || hash3[7] == Htarg && test_hash(hash3, (uint32_t *)ptarget)) { be32enc(&((uint32_t *)pdata)[19], data3[19]); *hashes_done = n; return true; @@ -537,7 +550,7 @@ int scanhash_scrypt(int thr_id, unsigned char *pdata, unsigned char *scratchbuf, } else { scrypt_1024_1_1_256_sp_2way(data, data2, hash, hash2, scratchbuf); } - if (hash2[7] <= Htarg) { + if (hash2[7] < Htarg || hash2[7] == Htarg && test_hash(hash2, (uint32_t *)ptarget)) { be32enc(&((uint32_t *)pdata)[19], data2[19]); *hashes_done = n; return true; @@ -549,7 +562,7 @@ int scanhash_scrypt(int thr_id, unsigned char *pdata, unsigned char *scratchbuf, scrypt_1024_1_1_256_sp(data, hash, scratchbuf); #endif - if (hash[7] <= Htarg) { + if (hash[7] < Htarg || hash[7] == Htarg && test_hash(hash, (uint32_t *)ptarget)) { be32enc(&((uint32_t *)pdata)[19], data[19]); *hashes_done = n; return true;