Browse Source

Merge remote-tracking branch 'upstream/master'

James Z.M. Gao 12 years ago
parent
commit
19be008900
7 changed files with 68 additions and 49 deletions
  1. 4 0
      README
  2. 44 22
      cgminer.c
  3. 3 2
      driver-cpu.c
  4. 1 17
      findnonce.c
  5. 1 0
      miner.h
  6. 12 5
      scrypt.c
  7. 3 3
      scrypt.h

+ 4 - 0
README

@@ -1045,6 +1045,10 @@ A: Your driver setup is failing to properly use the accessory GPUs. Your
 driver may be configured wrong or you have a driver version that needs a dummy
 plug on all the GPUs that aren't connected to a monitor.
 
+Q: Should I use crossfire/SLI?
+A: It does not benefit mining at all and depending on the GPU may actually
+worsen performance.
+
 Q: I have some random GPU performance related problem not addressed above.
 A: Seriously, it's the driver and/or SDK. Uninstall them and start again,
 noting there is no clean way to uninstall them so you have to use extra tools

+ 44 - 22
cgminer.c

@@ -2298,6 +2298,8 @@ static void reject_pool(struct pool *pool)
 	pool->enabled = POOL_REJECTING;
 }
 
+static void restart_threads(void);
+
 /* Theoretically threads could race when modifying accepted and
  * rejected values but the chance of two submits completing at the
  * same time is zero so there is no point adding extra locking */
@@ -2351,6 +2353,10 @@ share_result(json_t *val, json_t *res, json_t *err, const struct work *work,
 			enable_pool(pool);
 			switch_pools(NULL);
 		}
+		/* If we know we found the block we know better than anyone
+		 * that new work is needed. */
+		if (unlikely(work->block))
+			restart_threads();
 	} else {
 		mutex_lock(&stats_lock);
 		cgpu->rejected++;
@@ -5515,7 +5521,18 @@ void submit_work_async(struct work *work_in, struct timeval *tv_work_found)
 		quit(1, "Failed to create submit_work_thread");
 }
 
-static bool hashtest(struct thr_info *thr, struct work *work)
+void inc_hw_errors(struct thr_info *thr)
+{
+	mutex_lock(&stats_lock);
+	hw_errors++;
+	thr->cgpu->hw_errors++;
+	mutex_unlock(&stats_lock);
+
+	thr->cgpu->drv->hw_error(thr);
+}
+
+/* Returns 1 if meets difficulty target, 0 if not, -1 if hw error */
+static int hashtest(struct thr_info *thr, struct work *work)
 {
 	uint32_t *data32 = (uint32_t *)(work->data);
 	unsigned char swap[80];
@@ -5523,7 +5540,6 @@ static bool hashtest(struct thr_info *thr, struct work *work)
 	unsigned char hash1[32];
 	unsigned char hash2[32];
 	uint32_t *hash2_32 = (uint32_t *)hash2;
-	bool ret = false;
 
 	flip80(swap32, data32);
 	sha2(swap, 80, hash1);
@@ -5534,35 +5550,25 @@ static bool hashtest(struct thr_info *thr, struct work *work)
 		applog(LOG_WARNING, "%s%d: invalid nonce - HW error",
 				thr->cgpu->drv->name, thr->cgpu->device_id);
 
-		mutex_lock(&stats_lock);
-		hw_errors++;
-		thr->cgpu->hw_errors++;
-		mutex_unlock(&stats_lock);
-
-		thr->cgpu->drv->hw_error(thr);
-
-		goto out;
+		return -1;
 	}
 
-	mutex_lock(&stats_lock);
-	thr->cgpu->last_device_valid_work = time(NULL);
-	mutex_unlock(&stats_lock);
-
-	ret = fulltest(hash2, work->target);
-	if (!ret) {
+	if (!fulltest(hash2, work->target)) {
 		applog(LOG_INFO, "Share below target");
 		/* Check the diff of the share, even if it didn't reach the
 		 * target, just to set the best share value if it's higher. */
 		share_diff(work);
+		return 0;
 	}
-out:
-	return ret;
+
+	return 1;
 }
 
 void submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce)
 {
 	uint32_t *work_nonce = (uint32_t *)(work->data + 64 + 12);
 	struct timeval tv_work_found;
+	int valid;
 
 	gettimeofday(&tv_work_found, NULL);
 	*work_nonce = htole32(nonce);
@@ -5574,10 +5580,22 @@ void submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce)
 	mutex_unlock(&stats_lock);
 
 	/* Do one last check before attempting to submit the work */
-	if (!opt_scrypt && !hashtest(thr, work))
-		return;
+	if (opt_scrypt)
+		valid = scrypt_test(work->data, work->target, nonce);
+	else
+		valid = hashtest(thr, work);
 
-	submit_work_async(work, &tv_work_found);
+	if (unlikely(valid == -1))
+		return inc_hw_errors(thr);
+
+	mutex_lock(&stats_lock);
+	thr->cgpu->last_device_valid_work = time(NULL);
+	mutex_unlock(&stats_lock);
+
+	if (valid == 1)
+		submit_work_async(work, &tv_work_found);
+	else
+		applog(LOG_INFO, "Share below target");
 }
 
 static inline bool abandon_work(struct work *work, struct timeval *wdiff, uint64_t hashes)
@@ -6967,7 +6985,7 @@ struct _cgpu_devid_counter {
 	UT_hash_handle hh;
 };
 
-bool add_cgpu(struct cgpu_info*cgpu)
+bool add_cgpu(struct cgpu_info *cgpu)
 {
 	static struct _cgpu_devid_counter *devids = NULL;
 	struct _cgpu_devid_counter *d;
@@ -6986,6 +7004,10 @@ bool add_cgpu(struct cgpu_info*cgpu)
 	devices = realloc(devices, sizeof(struct cgpu_info *) * (total_devices + new_devices + 2));
 	wr_unlock(&devices_lock);
 
+	mutex_lock(&stats_lock);
+	cgpu->last_device_valid_work = time(NULL);
+	mutex_unlock(&stats_lock);
+
 	if (hotplug_mode)
 		devices[total_devices + new_devices++] = cgpu;
 	else

+ 3 - 2
driver-cpu.c

@@ -75,7 +75,6 @@ static inline void affine_to_cpu(int __maybe_unused id, int __maybe_unused cpu)
 
 
 /* TODO: resolve externals */
-extern void submit_work_async(const struct work *work_in, struct timeval *tv);
 extern char *set_int_range(const char *arg, int *i, int min, int max);
 extern int dev_from_id(int thr_id);
 
@@ -764,6 +763,8 @@ static void cpu_detect()
 		cgpu->deven = DEV_ENABLED;
 		cgpu->threads = 1;
 		cgpu->kname = algo_names[opt_algo];
+		if (opt_scrypt)
+			cgpu->drv->max_diff = 0xffffffff;
 		add_cgpu(cgpu);
 	}
 }
@@ -833,7 +834,7 @@ CPUSearch:
 	/* if nonce found, submit work */
 	if (unlikely(rc)) {
 		applog(LOG_DEBUG, "CPU %d found something?", dev_from_id(thr_id));
-		submit_work_async(work, NULL);
+		submit_nonce(thr, work, last_nonce);
 		work->blk.nonce = last_nonce + 1;
 		goto CPUSearch;
 	}

+ 1 - 17
findnonce.c

@@ -179,19 +179,6 @@ struct pc_data {
 	int found;
 };
 
-static void send_scrypt_nonce(struct pc_data *pcd, uint32_t nonce)
-{
-	struct thr_info *thr = pcd->thr;
-	struct work *work = pcd->work;
-
-	if (scrypt_test(work->data, work->target, nonce))
-		submit_nonce(thr, work, nonce);
-	else {
-		applog(LOG_INFO, "Scrypt error, review settings");
-		thr->cgpu->hw_errors++;
-	}
-}
-
 static void *postcalc_hash(void *userdata)
 {
 	struct pc_data *pcd = (struct pc_data *)userdata;
@@ -214,10 +201,7 @@ static void *postcalc_hash(void *userdata)
 		uint32_t nonce = pcd->res[entry];
 
 		applog(LOG_DEBUG, "OCL NONCE %u found in slot %d", nonce, entry);
-		if (opt_scrypt)
-			send_scrypt_nonce(pcd, nonce);
-		else
-			submit_nonce(thr, pcd->work, nonce);
+		submit_nonce(thr, pcd->work, nonce);
 	}
 
 	discard_work(pcd->work);

+ 1 - 0
miner.h

@@ -1201,6 +1201,7 @@ struct modminer_fpga_state {
 #endif
 
 extern void get_datestamp(char *, struct timeval *);
+extern void inc_hw_errors(struct thr_info *thr);
 extern void submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce);
 extern struct work *get_queued(struct cgpu_info *cgpu);
 extern struct work *__find_work_bymidstate(struct work *que, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen);

+ 12 - 5
scrypt.c

@@ -419,10 +419,12 @@ void scrypt_regenhash(struct work *work)
 	flip32(ohash, ohash);
 }
 
+static const uint32_t diff1targ = 0x0000ffff;
+
 /* Used externally as confirmation of correct OCL code */
-bool scrypt_test(unsigned char *pdata, const unsigned char *ptarget, uint32_t nonce)
+int scrypt_test(unsigned char *pdata, const unsigned char *ptarget, uint32_t nonce)
 {
-	uint32_t tmp_hash7, Htarg = ((const uint32_t *)ptarget)[7];
+	uint32_t tmp_hash7, Htarg = le32toh(((const uint32_t *)ptarget)[7]);
 	uint32_t data[20], ohash[8];
 	char *scratchbuf;
 
@@ -432,7 +434,12 @@ bool scrypt_test(unsigned char *pdata, const unsigned char *ptarget, uint32_t no
 	scrypt_1024_1_1_256_sp(data, scratchbuf, ohash);
 	tmp_hash7 = be32toh(ohash[7]);
 
-	return (tmp_hash7 <= Htarg);
+	applog(LOG_DEBUG, "harget %08lx diff1 %08lx hash %08lx", Htarg, diff1targ, tmp_hash7);
+	if (tmp_hash7 > diff1targ)
+		return -1;
+	if (tmp_hash7 > Htarg)
+		return 0;
+	return 1;
 }
 
 bool scanhash_scrypt(struct thr_info *thr, const unsigned char __maybe_unused *pmidstate,
@@ -444,7 +451,7 @@ bool scanhash_scrypt(struct thr_info *thr, const unsigned char __maybe_unused *p
 	char *scratchbuf;
 	uint32_t data[20];
 	uint32_t tmp_hash7;
-	uint32_t Htarg = ((const uint32_t *)ptarget)[7];
+	uint32_t Htarg = le32toh(((const uint32_t *)ptarget)[7]);
 	bool ret = false;
 
 	be32enc_vect(data, (const uint32_t *)pdata, 19);
@@ -459,7 +466,7 @@ bool scanhash_scrypt(struct thr_info *thr, const unsigned char __maybe_unused *p
 		uint32_t ostate[8];
 
 		*nonce = ++n;
-		data[19] = n;
+		data[19] = htobe32(n);
 		scrypt_1024_1_1_256_sp(data, scratchbuf, ostate);
 		tmp_hash7 = be32toh(ostate[7]);
 

+ 3 - 3
scrypt.h

@@ -4,16 +4,16 @@
 #include "miner.h"
 
 #ifdef USE_SCRYPT
-extern bool scrypt_test(unsigned char *pdata, const unsigned char *ptarget,
+extern int scrypt_test(unsigned char *pdata, const unsigned char *ptarget,
 			uint32_t nonce);
 extern void scrypt_regenhash(struct work *work);
 
 #else /* USE_SCRYPT */
-static inline bool scrypt_test(__maybe_unused unsigned char *pdata,
+static inline int scrypt_test(__maybe_unused unsigned char *pdata,
 			       __maybe_unused const unsigned char *ptarget,
 			       __maybe_unused uint32_t nonce)
 {
-	return false;
+	return 0;
 }
 
 static inline void scrypt_regenhash(__maybe_unused struct work *work)