Add optimized SHA-256d implementation for x86

This commit is contained in:
pooler 2012-03-31 16:44:59 +02:00
parent 7dd70bc05f
commit 9093f84686
4 changed files with 1257 additions and 40 deletions

View file

@ -15,7 +15,7 @@ bin_PROGRAMS = minerd
minerd_SOURCES = elist.h miner.h compat.h \ minerd_SOURCES = elist.h miner.h compat.h \
cpu-miner.c util.c \ cpu-miner.c util.c \
sha2.c sha2-x64.S \ sha2.c sha2-x86.S sha2-x64.S \
scrypt.c scrypt-x86.S scrypt-x64.S scrypt.c scrypt-x86.S scrypt-x64.S
minerd_LDFLAGS = $(PTHREAD_FLAGS) minerd_LDFLAGS = $(PTHREAD_FLAGS)
minerd_LDADD = @LIBCURL@ @JANSSON_LIBS@ @PTHREAD_LIBS@ @WS2_LIBS@ minerd_LDADD = @LIBCURL@ @JANSSON_LIBS@ @PTHREAD_LIBS@ @WS2_LIBS@

View file

@ -112,7 +112,7 @@ static inline void le32enc(void *pp, uint32_t x)
void sha256_init(uint32_t *state); void sha256_init(uint32_t *state);
void sha256_transform(uint32_t *state, const uint32_t *block, int swap); void sha256_transform(uint32_t *state, const uint32_t *block, int swap);
#if defined(__x86_64__) #if defined(__i386__) || defined(__x86_64__)
#define HAVE_SHA256_4WAY 1 #define HAVE_SHA256_4WAY 1
int sha256_use_4way(); int sha256_use_4way();
void sha256_init_4way(uint32_t *state); void sha256_init_4way(uint32_t *state);

1196
sha2-x86.S Normal file

File diff suppressed because it is too large Load diff

93
sha2.c
View file

@ -418,68 +418,89 @@ static inline void sha256d_ms(uint32_t *hash, uint32_t *W,
} }
#ifdef HAVE_SHA256_4WAY #ifdef HAVE_SHA256_4WAY
#define SHA256D_MAX_WAYS 4
void sha256d_ms_4way(uint32_t *hash, uint32_t *data, void sha256d_ms_4way(uint32_t *hash, uint32_t *data,
const uint32_t *midstate, const uint32_t *prehash); const uint32_t *midstate, const uint32_t *prehash);
#else
#define SHA256D_MAX_WAYS 1
#endif
int scanhash_sha256d(int thr_id, uint32_t *pdata, const uint32_t *ptarget, static inline int scanhash_sha256d_4way(int thr_id, uint32_t *pdata,
uint32_t max_nonce, unsigned long *hashes_done) const uint32_t *ptarget, uint32_t max_nonce, unsigned long *hashes_done)
{ {
uint32_t data[SHA256D_MAX_WAYS * 64] __attribute__((aligned(128))); uint32_t data[4 * 64] __attribute__((aligned(128)));
uint32_t hash[SHA256D_MAX_WAYS * 8] __attribute__((aligned(32))); uint32_t hash[4 * 8] __attribute__((aligned(32)));
uint32_t midstate[SHA256D_MAX_WAYS * 8] __attribute__((aligned(32))); uint32_t midstate[4 * 8] __attribute__((aligned(32)));
uint32_t prehash[SHA256D_MAX_WAYS * 8] __attribute__((aligned(32))); uint32_t prehash[4 * 8] __attribute__((aligned(32)));
uint32_t n = pdata[19] - 1; uint32_t n = pdata[19] - 1;
const uint32_t first_nonce = pdata[19]; const uint32_t first_nonce = pdata[19];
const uint32_t Htarg = ptarget[7]; const uint32_t Htarg = ptarget[7];
#ifdef HAVE_SHA256_4WAY
const int ways = sha256_use_4way() ? 4 : 1;
#else
const int ways = 1;
#endif
int i, j; int i, j;
memcpy(data, pdata + 16, 64); memcpy(data, pdata + 16, 64);
sha256d_preextend(data); sha256d_preextend(data);
for (i = 31; i >= 0; i--) for (i = 31; i >= 0; i--)
for (j = 0; j < ways; j++) for (j = 0; j < 4; j++)
data[i * ways + j] = data[i]; data[i * 4 + j] = data[i];
sha256_init(midstate); sha256_init(midstate);
sha256_transform(midstate, pdata, 0); sha256_transform(midstate, pdata, 0);
memcpy(prehash, midstate, 32); memcpy(prehash, midstate, 32);
sha256d_prehash(prehash, pdata + 16); sha256d_prehash(prehash, pdata + 16);
for (i = 7; i >= 0; i--) { for (i = 7; i >= 0; i--) {
for (j = 0; j < ways; j++) { for (j = 0; j < 4; j++) {
midstate[i * ways + j] = midstate[i]; midstate[i * 4 + j] = midstate[i];
prehash[i * ways + j] = prehash[i]; prehash[i * 4 + j] = prehash[i];
} }
} }
#ifdef HAVE_SHA256_4WAY do {
if (ways == 4) for (i = 0; i < 4; i++)
do { data[4 * 3 + i] = ++n;
for (i = 0; i < 4; i++)
data[4 * 3 + i] = ++n;
sha256d_ms_4way(hash, data, midstate, prehash); sha256d_ms_4way(hash, data, midstate, prehash);
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
if (hash[4 * 7 + i] <= Htarg) { if (hash[4 * 7 + i] <= Htarg) {
pdata[19] = data[4 * 3 + i]; pdata[19] = data[4 * 3 + i];
sha256d(hash, pdata); sha256d(hash, pdata);
if (fulltest(hash, ptarget)) { if (fulltest(hash, ptarget)) {
*hashes_done = n - first_nonce + 1; *hashes_done = n - first_nonce + 1;
return 1; return 1;
}
} }
} }
} while (n < max_nonce && !work_restart[thr_id].restart); }
else } while (n < max_nonce && !work_restart[thr_id].restart);
*hashes_done = n - first_nonce + 1;
pdata[19] = n;
return 0;
}
#endif /* HAVE_SHA256_4WAY */
int scanhash_sha256d(int thr_id, uint32_t *pdata, const uint32_t *ptarget,
uint32_t max_nonce, unsigned long *hashes_done)
{
uint32_t data[64] __attribute__((aligned(128)));
uint32_t hash[8] __attribute__((aligned(32)));
uint32_t midstate[8] __attribute__((aligned(32)));
uint32_t prehash[8] __attribute__((aligned(32)));
uint32_t n = pdata[19] - 1;
const uint32_t first_nonce = pdata[19];
const uint32_t Htarg = ptarget[7];
#ifdef HAVE_SHA256_4WAY
if (sha256_use_4way())
return scanhash_sha256d_4way(thr_id, pdata, ptarget,
max_nonce, hashes_done);
#endif #endif
memcpy(data, pdata + 16, 64);
sha256d_preextend(data);
sha256_init(midstate);
sha256_transform(midstate, pdata, 0);
memcpy(prehash, midstate, 32);
sha256d_prehash(prehash, pdata + 16);
do { do {
data[3] = ++n; data[3] = ++n;
sha256d_ms(hash, data, midstate, prehash); sha256d_ms(hash, data, midstate, prehash);