Browse Source

ztex: precheck the secondary solutions to avoid hw errors

the ztex bitstreams gives back the latest checked nonce and
its hash7 value and two possible solutions.

every 250ms the latest nonce is checked and compared with hash7
to count hw errors and adapt the MHz value. one change is to
use the solutions even if the latest nonce is not correct. the
original java ztex code also does it this way.

since the second solution is often not correct we have alot
of hw errors. now we always check the second solution before
we submit it to the cgminer main code.

the java code also ignores all hw errors 500ms after a sendHash.
we now do the same. this can possibly yield in a higher MHz rate.
but the chance is so low nobody will ever notice in practice.
nfactor-troky
Denis Ahrens 12 years ago
parent
commit
ccee686aee
  1. 64
      driver-ztex.c
  2. 7
      libztex.c

64
driver-ztex.c

@ -146,9 +146,7 @@ static bool ztex_updateFreq(struct libztex_device* ztex)
} }
static bool ztex_checkNonce(struct libztex_device *ztex, static uint32_t ztex_checkNonce(struct work *work, uint32_t nonce)
struct work *work,
struct libztex_hash_data *hdata)
{ {
uint32_t *data32 = (uint32_t *)(work->data); uint32_t *data32 = (uint32_t *)(work->data);
unsigned char swap[80]; unsigned char swap[80];
@ -158,31 +156,15 @@ static bool ztex_checkNonce(struct libztex_device *ztex,
uint32_t *hash2_32 = (uint32_t *)hash2; uint32_t *hash2_32 = (uint32_t *)hash2;
int i; int i;
#if defined(__BIGENDIAN__) || defined(MIPSEB) swap32[76/4] = htonl(nonce);
hdata->nonce = swab32(hdata->nonce);
hdata->hash7 = swab32(hdata->hash7);
#endif
work->data[64 + 12 + 0] = (hdata->nonce >> 0) & 0xff; for (i = 0; i < 76 / 4; i++)
work->data[64 + 12 + 1] = (hdata->nonce >> 8) & 0xff;
work->data[64 + 12 + 2] = (hdata->nonce >> 16) & 0xff;
work->data[64 + 12 + 3] = (hdata->nonce >> 24) & 0xff;
for (i = 0; i < 80 / 4; i++)
swap32[i] = swab32(data32[i]); swap32[i] = swab32(data32[i]);
sha2(swap, 80, hash1); sha2(swap, 80, hash1);
sha2(hash1, 32, hash2); sha2(hash1, 32, hash2);
#if defined(__BIGENDIAN__) || defined(MIPSEB)
if (hash2_32[7] != ((hdata->hash7 + 0x5be0cd19) & 0xFFFFFFFF)) { return htonl(hash2_32[7]);
#else
if (swab32(hash2_32[7]) != ((hdata->hash7 + 0x5be0cd19) & 0xFFFFFFFF)) {
#endif
ztex->errorCount[ztex->freqM] += 1.0 / ztex->numNonces;
applog(LOG_DEBUG, "%s: checkNonce failed for %0.8X", ztex->repr, hdata->nonce);
return false;
}
return true;
} }
static int64_t ztex_scanhash(struct thr_info *thr, struct work *work, static int64_t ztex_scanhash(struct thr_info *thr, struct work *work,
@ -240,9 +222,11 @@ static int64_t ztex_scanhash(struct thr_info *thr, struct work *work,
} }
overflow = false; overflow = false;
int count = 0;
applog(LOG_DEBUG, "%s: entering poll loop", ztex->repr); applog(LOG_DEBUG, "%s: entering poll loop", ztex->repr);
while (!(overflow || thr->work_restart)) { while (!(overflow || thr->work_restart)) {
count++;
nmsleep(250); nmsleep(250);
if (thr->work_restart) { if (thr->work_restart) {
applog(LOG_DEBUG, "%s: New work detected", ztex->repr); applog(LOG_DEBUG, "%s: New work detected", ztex->repr);
@ -277,9 +261,6 @@ static int64_t ztex_scanhash(struct thr_info *thr, struct work *work,
for (i = 0; i < ztex->numNonces; i++) { for (i = 0; i < ztex->numNonces; i++) {
nonce = hdata[i].nonce; nonce = hdata[i].nonce;
#if defined(__BIGENDIAN__) || defined(MIPSEB)
nonce = swab32(nonce);
#endif
if (nonce > noncecnt) if (nonce > noncecnt)
noncecnt = nonce; noncecnt = nonce;
if (((0xffffffff - nonce) < (nonce - lastnonce[i])) || nonce < lastnonce[i]) { if (((0xffffffff - nonce) < (nonce - lastnonce[i])) || nonce < lastnonce[i]) {
@ -287,16 +268,29 @@ static int64_t ztex_scanhash(struct thr_info *thr, struct work *work,
overflow = true; overflow = true;
} else } else
lastnonce[i] = nonce; lastnonce[i] = nonce;
#if !(defined(__BIGENDIAN__) || defined(MIPSEB))
nonce = swab32(nonce); if (ztex_checkNonce(work, nonce) != (hdata->hash7 + 0x5be0cd19)) {
#endif applog(LOG_DEBUG, "%s: checkNonce failed for %0.8X", ztex->repr, nonce);
if (!ztex_checkNonce(ztex, work, &hdata[i])) {
// do not count errors in the first 500ms after sendHashData (2x250 wait time)
if (count > 2) {
ztex->errorCount[ztex->freqM] += 1.0 / ztex->numNonces;
thr->cgpu->hw_errors++; thr->cgpu->hw_errors++;
continue;
} }
}
for (j=0; j<=ztex->extraSolutions; j++) { for (j=0; j<=ztex->extraSolutions; j++) {
nonce = hdata[i].goldenNonce[j]; nonce = hdata[i].goldenNonce[j];
if (nonce > 0) {
if (nonce == ztex->offsNonces) {
continue;
}
// precheck the extraSolutions since they often fail
if (j > 0 && ztex_checkNonce(work, nonce) != 0) {
continue;
}
found = false; found = false;
for (k = 0; k < backlog_max; k++) { for (k = 0; k < backlog_max; k++) {
if (backlog[k] == nonce) { if (backlog[k] == nonce) {
@ -307,11 +301,10 @@ static int64_t ztex_scanhash(struct thr_info *thr, struct work *work,
if (!found) { if (!found) {
applog(LOG_DEBUG, "%s: Share found N%dE%d", ztex->repr, i, j); applog(LOG_DEBUG, "%s: Share found N%dE%d", ztex->repr, i, j);
backlog[backlog_p++] = nonce; backlog[backlog_p++] = nonce;
if (backlog_p >= backlog_max) if (backlog_p >= backlog_max)
backlog_p = 0; backlog_p = 0;
#if defined(__BIGENDIAN__) || defined(MIPSEB)
nonce = swab32(nonce);
#endif
work->blk.nonce = 0xffffffff; work->blk.nonce = 0xffffffff;
submit_nonce(thr, work, nonce); submit_nonce(thr, work, nonce);
applog(LOG_DEBUG, "%s: submitted %0.8x", ztex->repr, nonce); applog(LOG_DEBUG, "%s: submitted %0.8x", ztex->repr, nonce);
@ -319,7 +312,6 @@ static int64_t ztex_scanhash(struct thr_info *thr, struct work *work,
} }
} }
} }
}
ztex->errorRate[ztex->freqM] = ztex->errorCount[ztex->freqM] / ztex->errorWeight[ztex->freqM] * (ztex->errorWeight[ztex->freqM] < 100? ztex->errorWeight[ztex->freqM] * 0.01: 1.0); ztex->errorRate[ztex->freqM] = ztex->errorCount[ztex->freqM] / ztex->errorWeight[ztex->freqM] * (ztex->errorWeight[ztex->freqM] < 100? ztex->errorWeight[ztex->freqM] * 0.01: 1.0);
if (ztex->errorRate[ztex->freqM] > ztex->maxErrorRate[ztex->freqM]) if (ztex->errorRate[ztex->freqM] > ztex->maxErrorRate[ztex->freqM])

7
libztex.c

@ -878,11 +878,16 @@ int libztex_readHashData(struct libztex_device *ztex, struct libztex_hash_data n
//applog(LOG_DEBUG, "W %d:0 %0.8x", i, nonces[i].goldenNonce[0]); //applog(LOG_DEBUG, "W %d:0 %0.8x", i, nonces[i].goldenNonce[0]);
memcpy((char*)&nonces[i].nonce, &rbuf[(i*bufsize)+4], 4); memcpy((char*)&nonces[i].nonce, &rbuf[(i*bufsize)+4], 4);
nonces[i].nonce -= ztex->offsNonces;
memcpy((char*)&nonces[i].hash7, &rbuf[(i*bufsize)+8], 4); memcpy((char*)&nonces[i].hash7, &rbuf[(i*bufsize)+8], 4);
nonces[i].nonce = htole32(nonces[i].nonce);
nonces[i].hash7 = htole32(nonces[i].hash7);
nonces[i].nonce -= ztex->offsNonces;
for (j=0; j<ztex->extraSolutions; j++) { for (j=0; j<ztex->extraSolutions; j++) {
memcpy((char*)&nonces[i].goldenNonce[j+1], &rbuf[(i*bufsize)+12+(j*4)], 4); memcpy((char*)&nonces[i].goldenNonce[j+1], &rbuf[(i*bufsize)+12+(j*4)], 4);
nonces[i].goldenNonce[j+1] = htole32(nonces[i].goldenNonce[j+1]);
nonces[i].goldenNonce[j+1] -= ztex->offsNonces; nonces[i].goldenNonce[j+1] -= ztex->offsNonces;
//applog(LOG_DEBUG, "W %d:%d %0.8x", i, j+1, nonces[i].goldenNonce[j+1]); //applog(LOG_DEBUG, "W %d:%d %0.8x", i, j+1, nonces[i].goldenNonce[j+1]);
} }

Loading…
Cancel
Save