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
This commit is contained in:
pooler 2012-01-17 00:38:06 +01:00
parent a4d636a645
commit e0dc6649e1
9 changed files with 102 additions and 166 deletions

View file

@ -2,6 +2,4 @@ Jeff Garzik <jgarzik@pobox.com>
ArtForz ArtForz
<very tiny tweaks> Lolcust
pooler <pooler@litecoinpool.org> pooler <pooler@litecoinpool.org>

13
NEWS
View file

@ -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 - Linux x86_64 optimisations - Con Kolivas
- Optimise for x86_64 by default by using sse2_64 algo - Optimise for x86_64 by default by using sse2_64 algo
- Detects CPUs and sets number of threads accordingly - Detects CPUs and sets number of threads accordingly

7
README
View file

@ -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. License: GPLv2. See COPYING for details.
@ -10,13 +11,13 @@ Dependencies:
Basic *nix build instructions: Basic *nix build instructions:
./autogen.sh # only needed if building from git repo ./autogen.sh # only needed if building from git repo
CFLAGS="-O3 -Wall -msse2" ./configure ./configure CFLAGS="-O3"
make make
Basic WIN32 build instructions (on Fedora 13; requires mingw32): Basic WIN32 build instructions (on Fedora 13; requires mingw32):
./autogen.sh # only needed if building from git repo ./autogen.sh # only needed if building from git repo
rm -f mingw32-config.cache rm -f mingw32-config.cache
MINGW32_CFLAGS="-O3 -Wall -msse2" mingw32-configure MINGW32_CFLAGS="-O3" mingw32-configure
make make
./mknsis.sh ./mknsis.sh

View file

@ -16,8 +16,7 @@ enum {
static inline int setpriority(int which, int who, int prio) static inline int setpriority(int which, int who, int prio)
{ {
/* FIXME - actually do something */ return -!SetPriorityClass(GetCurrentProcess(), IDLE_PRIORITY_CLASS);
return 0;
} }
#endif /* WIN32 */ #endif /* WIN32 */

View file

@ -1,4 +1,4 @@
AC_INIT([cpuminer], [1.0.2]) AC_INIT([cpuminer], [2.0])
AC_PREREQ(2.52) AC_PREREQ(2.52)
AC_CANONICAL_SYSTEM AC_CANONICAL_SYSTEM

View file

@ -23,6 +23,7 @@
#include <windows.h> #include <windows.h>
#else #else
#include <sys/resource.h> #include <sys/resource.h>
#include <sys/sysctl.h>
#endif #endif
#include <getopt.h> #include <getopt.h>
#include <jansson.h> #include <jansson.h>
@ -126,35 +127,33 @@ static struct option_help options_help[] = {
"(-h) Display this help text" }, "(-h) Display this help text" },
{ "config FILE", { "config FILE",
"(-c FILE) JSON-format configuration file (default: none)\n" "(-c FILE) Load a JSON-format configuration file" },
"See example-cfg.json for an example configuration." },
{ "algo XXX", { "algo XXX",
"(-a XXX) Only scrypt (e.g. --algo scrypt) is supported" }, "(-a XXX) Specify the algorithm to use (default: scrypt)" },
{ "quiet", { "quiet",
"(-q) Disable per-thread hashmeter output (default: off)" }, "(-q) Disable per-thread hashmeter output" },
{ "debug", { "debug",
"(-D) Enable debug output (default: off)" }, "(-D) Enable debug output" },
{ "no-longpoll", { "no-longpoll",
"Disable X-Long-Polling support (default: enabled)" }, "Disable X-Long-Polling support" },
{ "protocol-dump", { "protocol-dump",
"(-P) Verbose dump of protocol-level activities (default: off)" }, "(-P) Verbose dump of protocol-level activities" },
{ "retries N", { "retries N",
"(-r N) Number of times to retry if JSON-RPC call fails\n" "(-r N) Number of times to retry if JSON-RPC call fails\n"
"\t(default: retry indefinitely)" }, "\t(default: retry indefinitely)" },
{ "retry-pause N", { "retry-pause N",
"(-R N) Number of seconds to pause between retries\n" "(-R N) Number of seconds to pause between retries (default: 30)" },
"\t(default: 30)" },
{ "scantime N", { "scantime N",
"(-s N) Upper bound on time spent scanning current work,\n" "(-s N) Upper bound on time spent scanning current work, in seconds\n"
"\tin seconds. (default: 5)" }, "\t(default: 5)" },
{ "timeout N", { "timeout N",
"(-T N) Connection timeout, in seconds (default: 180)" }, "(-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)" }, "(-t N) Number of miner threads (default: number of processors)" },
{ "url URL", { "url URL",
"URL for JSON-RPC server " "(-o URL) URL for JSON-RPC server "
"(default: " DEF_RPC_URL ")" }, "(default: " DEF_RPC_URL ")" },
{ "userpass USERNAME:PASSWORD", { "userpass USERNAME:PASSWORD",
"Username:Password pair for JSON-RPC server" }, "(-O USERNAME:PASSWORD) Username:Password pair for JSON-RPC server" },
{ "user USERNAME", { "user USERNAME",
"(-u USERNAME) Username for JSON-RPC server" }, "(-u USERNAME) Username for JSON-RPC server" },
@ -198,9 +197,9 @@ static struct option options[] = {
#ifdef HAVE_SYSLOG_H #ifdef HAVE_SYSLOG_H
{ "syslog", 0, NULL, 1004 }, { "syslog", 0, NULL, 1004 },
#endif #endif
{ "url", 1, NULL, 1001 }, { "url", 1, NULL, 'o' },
{ "user", 1, NULL, 'u' }, { "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); free(rpc_user);
rpc_user = strdup(arg); rpc_user = strdup(arg);
break; break;
case 1001: /* --url */ case 'o': /* --url */
if (strncmp(arg, "http://", 7) && if (strncmp(arg, "http://", 7) &&
strncmp(arg, "https://", 8)) strncmp(arg, "https://", 8))
show_usage(); show_usage();
@ -792,7 +791,7 @@ static void parse_arg (int key, char *arg)
free(rpc_url); free(rpc_url);
rpc_url = strdup(arg); rpc_url = strdup(arg);
break; break;
case 1002: /* --userpass */ case 'O': /* --userpass */
if (!strchr(arg, ':')) if (!strchr(arg, ':'))
show_usage(); show_usage();
@ -813,9 +812,17 @@ static void parse_arg (int key, char *arg)
SYSTEM_INFO sysinfo; SYSTEM_INFO sysinfo;
GetSystemInfo(&sysinfo); GetSystemInfo(&sysinfo);
num_processors = sysinfo.dwNumberOfProcessors; num_processors = sysinfo.dwNumberOfProcessors;
#else #elif defined(_SC_NPROCESSORS_ONLN)
num_processors = sysconf(_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 #endif
if (num_processors < 1)
num_processors = 1;
if (!opt_n_threads) if (!opt_n_threads)
opt_n_threads = num_processors; opt_n_threads = num_processors;
} }
@ -857,7 +864,7 @@ static void parse_cmdline(int argc, char *argv[])
int key; int key;
while (1) { 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) if (key < 0)
break; break;

View file

@ -2,11 +2,11 @@
"_comment1" : "Any long-format command line argument ", "_comment1" : "Any long-format command line argument ",
"_comment2" : "may be used in this JSON configuration file", "_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", "user" : "rpcuser",
"pass" : "rpcpass", "pass" : "rpcpass",
"algo" : "sse2_64", "algo" : "scrypt",
"threads" : "4", "threads" : "4",
"quiet" : true "quiet" : true

View file

@ -28,6 +28,41 @@
#if defined(__i386__) #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 .macro gen_salsa8_core_quadround
movl 52(%esp), %ecx movl 52(%esp), %ecx
movl 4(%esp), %edx movl 4(%esp), %edx
@ -648,73 +683,8 @@ xmm_scrypt_core:
subl $128, %esp subl $128, %esp
andl $-16, %esp andl $-16, %esp
# shuffle 1st block to (%esp) scrypt_shuffle %edi, 0, %esp, 0
movl 60(%edi), %edx scrypt_shuffle %edi, 64, %esp, 64
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)
movdqa 96(%esp), %xmm6 movdqa 96(%esp), %xmm6
movdqa 112(%esp), %xmm7 movdqa 112(%esp), %xmm7
@ -834,73 +804,8 @@ xmm_scrypt_core_loop2:
movdqa %xmm6, 96(%esp) movdqa %xmm6, 96(%esp)
movdqa %xmm7, 112(%esp) movdqa %xmm7, 112(%esp)
# re-shuffle 1st block back scrypt_shuffle %esp, 0, %edi, 0
movl 60(%esp), %edx scrypt_shuffle %esp, 64, %edi, 64
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)
movl %ebp, %esp movl %ebp, %esp
popl %esi popl %esi

View file

@ -497,6 +497,19 @@ static void scrypt_1024_1_1_256_sp_3way(const uint32_t *input1, const uint32_t *
#endif #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, int scanhash_scrypt(int thr_id, unsigned char *pdata, unsigned char *scratchbuf,
const unsigned char *ptarget, const unsigned char *ptarget,
uint32_t max_nonce, unsigned long *hashes_done) 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) { if (throughput >= 3 && n < max_nonce) {
data3[19] = n++; data3[19] = n++;
scrypt_1024_1_1_256_sp_3way(data, data2, data3, hash, hash2, hash3, scratchbuf); 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]); be32enc(&((uint32_t *)pdata)[19], data3[19]);
*hashes_done = n; *hashes_done = n;
return true; return true;
@ -537,7 +550,7 @@ int scanhash_scrypt(int thr_id, unsigned char *pdata, unsigned char *scratchbuf,
} else { } else {
scrypt_1024_1_1_256_sp_2way(data, data2, hash, hash2, scratchbuf); 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]); be32enc(&((uint32_t *)pdata)[19], data2[19]);
*hashes_done = n; *hashes_done = n;
return true; 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); scrypt_1024_1_1_256_sp(data, hash, scratchbuf);
#endif #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]); be32enc(&((uint32_t *)pdata)[19], data[19]);
*hashes_done = n; *hashes_done = n;
return true; return true;