Browse Source

Merge branch 'cg_new_dynintensity' into stratum

Conflicts:
	configure.ac
Luke Dashjr 13 years ago
parent
commit
a6d18b3af0
6 changed files with 54 additions and 63 deletions
  1. 0 1
      Makefile.am
  2. 1 5
      configure.ac
  3. 25 47
      driver-opencl.c
  4. 16 7
      miner.c
  5. 6 3
      miner.h
  6. 6 0
      util.c

+ 0 - 1
Makefile.am

@@ -17,7 +17,6 @@ bin_SCRIPTS	= *.cl
 bfgminer_LDFLAGS	= $(PTHREAD_FLAGS)
 bfgminer_LDADD	= $(DLOPEN_FLAGS) @LIBCURL_LIBS@ @JANSSON_LIBS@ @PTHREAD_LIBS@ \
 		  @NCURSES_LIBS@ @PDCURSES_LIBS@ @WS2_LIBS@ \
-		  @TIMER_LIBS@ \
 		  @UDEV_LIBS@ @USB_LIBS@ \
 		  @MATH_LIBS@ lib/libgnu.a ccan/libccan.a
 bfgminer_CPPFLAGS = -I$(top_builddir)/lib -I$(top_srcdir)/lib

+ 1 - 5
configure.ac

@@ -69,7 +69,6 @@ USB_LIBS=""
 USB_FLAGS=""
 DLOPEN_FLAGS="-ldl"
 WS2_LIBS=""
-TIMER_LIBS=""
 MATH_LIBS="-lm"
 
 case $target in
@@ -88,7 +87,6 @@ case $target in
 	PTHREAD_FLAGS=""
 	DLOPEN_FLAGS=""
 	WS2_LIBS="-lws2_32"
-	TIMER_LIBS="-lwinmm"
 	;;
   *-*-mingw*)
     have_x86_64=false
@@ -96,7 +94,6 @@ case $target in
     PTHREAD_FLAGS=""
     DLOPEN_FLAGS=""
     WS2_LIBS="-lws2_32"
-	TIMER_LIBS="-lwinmm"
     AC_DEFINE([_WIN32_WINNT], [0x0501], "WinNT version for XP+ support")
     ;;
   *-*-cygwin*)
@@ -416,7 +413,6 @@ AC_SUBST(NCURSES_CPPFLAGS)
 AC_SUBST(NCURSES_LIBS)
 AC_SUBST(PDCURSES_LIBS)
 AC_SUBST(WS2_LIBS)
-AC_SUBST(TIMER_LIBS)
 AC_SUBST(MATH_LIBS)
 AC_SUBST(UDEV_LIBS)
 AC_SUBST(USB_LIBS)
@@ -509,7 +505,7 @@ echo "Compilation............: make (or gmake)"
 echo "  CPPFLAGS.............: $CPPFLAGS $NCURSES_CPPFLAGS"
 echo "  CFLAGS...............: $CFLAGS"
 echo "  LDFLAGS..............: $LDFLAGS $PTHREAD_FLAGS $USB_FLAGS"
-echo "  LDADD................: $DLOPEN_FLAGS $LIBCURL_LIBS $JANSSON_LIBS $PTHREAD_LIBS $NCURSES_LIBS $PDCURSES_LIBS $WS2_LIBS $TIMER_LIBS $MATH_LIBS $UDEV_LIBS $USB_LIBS"
+echo "  LDADD................: $DLOPEN_FLAGS $LIBCURL_LIBS $JANSSON_LIBS $PTHREAD_LIBS $NCURSES_LIBS $PDCURSES_LIBS $WS2_LIBS $MATH_LIBS $UDEV_LIBS $USB_LIBS"
 echo
 echo "Installation...........: make install (as root if needed, with 'su' or 'sudo')"
 echo "  prefix...............: $prefix"

+ 25 - 47
driver-opencl.c

@@ -800,21 +800,6 @@ struct cgpu_info *cpus;
 
 #ifdef HAVE_OPENCL
 
-#ifdef WIN32
-static UINT timeperiod_set;
-#endif
-
-void opencl_dynamic_cleanup() {
-#ifdef WIN32
-	if (timeperiod_set) {
-		timeEndPeriod(timeperiod_set);
-		timeperiod_set = 0;
-	}
-#endif
-}
-
-extern int opt_dynamic_interval;
-
 /* In dynamic mode, only the first thread of each device will be in use.
  * This potentially could start a thread that was stopped with the start-stop
  * options if one were to disable dynamic from the menu on a paused GPU */
@@ -822,18 +807,10 @@ void pause_dynamic_threads(int gpu)
 {
 	struct cgpu_info *cgpu = &gpus[gpu];
 	int i;
-#ifdef WIN32
-	bool any_dynamic = false;
-#endif
 
 	for (i = 1; i < cgpu->threads; i++) {
 		struct thr_info *thr = &thr_info[i];
 
-#ifdef WIN32
-		if (cgpu->dynamic)
-			any_dynamic = true;
-#endif
-
 		if (!thr->pause && cgpu->dynamic) {
 			applog(LOG_WARNING, "Disabling extra threads due to dynamic mode.");
 			applog(LOG_WARNING, "Tune dynamic intensity with --gpu-dyninterval");
@@ -843,20 +820,6 @@ void pause_dynamic_threads(int gpu)
 		if (!cgpu->dynamic && cgpu->deven != DEV_DISABLED)
 			tq_push(thr->q, &ping);
 	}
-
-#ifdef WIN32
-	if (any_dynamic) {
-		if (!timeperiod_set) {
-			timeperiod_set = opt_dynamic_interval > 3 ? (opt_dynamic_interval / 2) : 1;
-			if (TIMERR_NOERROR != timeBeginPeriod(timeperiod_set))
-				timeperiod_set = 0;
-		}
-	} else {
-		if (timeperiod_set) {
-			opencl_dynamic_cleanup();
-		}
-	}
-#endif
 }
 
 
@@ -1753,6 +1716,7 @@ static int64_t opencl_scanhash(struct thr_info *thr, struct work *work,
 	_clState *clState = clStates[thr_id];
 	const cl_kernel *kernel = &clState->kernel;
 	const int dynamic_us = opt_dynamic_interval * 1000;
+	struct timeval tv_gpuend;
 
 	cl_int status;
 	size_t globalThreads[1];
@@ -1788,7 +1752,17 @@ static int64_t opencl_scanhash(struct thr_info *thr, struct work *work,
 		clFinish(clState->commandQueue);
 	}
 
-	gettimeofday(&gpu->tv_gpustart, NULL);
+	if (gpu->dynamic) {
+		gettimeofday(&gpu->tv_gpumid, NULL);
+		if (gpu->new_work) {
+			gpu->new_work = false;
+			gpu->intervals = gpu->hit = 0;
+		}
+		if (!gpu->intervals) {
+			gpu->tv_gpustart.tv_sec = gpu->tv_gpumid.tv_sec;
+			gpu->tv_gpustart.tv_usec = gpu->tv_gpumid.tv_usec;
+		}
+	}
 
 	status = thrdata->queue_kernel_parameters(clState, &work->blk, globalThreads[0]);
 	if (unlikely(status != CL_SUCCESS)) {
@@ -1818,26 +1792,30 @@ static int64_t opencl_scanhash(struct thr_info *thr, struct work *work,
 	}
 
 	if (gpu->dynamic) {
-		struct timeval diff;
-		suseconds_t gpu_us;
+		double gpu_us;
 
 		clFinish(clState->commandQueue);
-		gettimeofday(&gpu->tv_gpuend, NULL);
-		timersub(&gpu->tv_gpuend, &gpu->tv_gpustart, &diff);
-		gpu_us = diff.tv_sec * 1000000 + diff.tv_usec;
-		if (likely(gpu_us >= 0)) {
-			gpu->gpu_us_average = (gpu->gpu_us_average + gpu_us * 0.63) / 1.63;
+		/* Windows returns the same time for gettimeofday due to its
+		 * 15ms timer resolution, so we must average the result over
+		 * at least 5 values that are actually different to get an
+		 * accurate result */
+		gpu->intervals++;
+		gettimeofday(&tv_gpuend, NULL);
+		gpu_us = us_tdiff(&tv_gpuend, &gpu->tv_gpumid);
+		if (gpu_us > 0 && ++gpu->hit > 4) {
+			gpu_us = us_tdiff(&tv_gpuend, &gpu->tv_gpustart) / gpu->intervals;
 
 			/* Try to not let the GPU be out for longer than
 			 * opt_dynamic_interval in ms, but increase
 			 * intensity when the system is idle in dynamic mode */
-			if (gpu->gpu_us_average > dynamic_us) {
+			if (gpu_us > dynamic_us) {
 				if (gpu->intensity > MIN_INTENSITY)
 					--gpu->intensity;
-			} else if (gpu->gpu_us_average < dynamic_us / 2) {
+			} else if (gpu_us < dynamic_us / 2) {
 				if (gpu->intensity < MAX_INTENSITY)
 					++gpu->intensity;
 			}
+			gpu->intervals = gpu->hit = 0;
 		}
 	}
 

+ 16 - 7
miner.c

@@ -3277,7 +3277,7 @@ static bool stale_work(struct work *work, bool share)
 
 	if (share) {
 		/* If the share isn't on this pool's latest block, it's stale */
-		if (pool->block_id != block_id)
+		if (pool->block_id && pool->block_id != block_id)
 		{
 			applog(LOG_DEBUG, "Share stale due to block mismatch (%08lx != %08lx)", (long)block_id, (long)pool->block_id);
 			return true;
@@ -3293,10 +3293,18 @@ static bool stale_work(struct work *work, bool share)
 	} else {
 		/* If this work isn't for the latest Bitcoin block, it's stale */
 		/* But only care about the current pool if failover-only */
-		if (block_id != ((enabled_pools <= 1 || opt_fail_only) ? pool->block_id : current_block_id))
-		{
-			applog(LOG_DEBUG, "Work stale due to block mismatch (%08lx != %d ? %08lx : %08lx)", (long)block_id, (int)opt_fail_only, (long)pool->block_id, (long)current_block_id);
-			return true;
+		if (enabled_pools <= 1 || opt_fail_only) {
+			if (pool->block_id && block_id != pool->block_id)
+			{
+				applog(LOG_DEBUG, "Work stale due to block mismatch (%08lx != 1 ? %08lx : %08lx)", (long)block_id, (long)pool->block_id, (long)current_block_id);
+				return true;
+			}
+		} else {
+			if (block_id != current_block_id)
+			{
+				applog(LOG_DEBUG, "Work stale due to block mismatch (%08lx != 0 ? %08lx : %08lx)", (long)block_id, (long)pool->block_id, (long)current_block_id);
+				return true;
+			}
 		}
 
 		/* If the pool has asked us to restart since this work, it's stale */
@@ -3580,7 +3588,6 @@ void switch_pools(struct pool *selected)
 
 	currentpool = pools[pool_no];
 	pool = currentpool;
-	pool->block_id = 0;
 	mutex_unlock(&control_lock);
 
 	/* Set the lagging flag to avoid pool not providing work fast enough
@@ -3590,7 +3597,10 @@ void switch_pools(struct pool *selected)
 		pool_tset(pool, &pool->lagging);
 
 	if (pool != last_pool)
+	{
+		pool->block_id = 0;
 		applog(LOG_WARNING, "Switching to %s", pool->rpc_url);
+	}
 
 	mutex_lock(&lp_lock);
 	pthread_cond_broadcast(&lp_cond);
@@ -6634,7 +6644,6 @@ static void clean_up(void)
 {
 #ifdef HAVE_OPENCL
 	clear_adl(nDevs);
-	opencl_dynamic_cleanup();
 #endif
 #ifdef HAVE_LIBUSB
         libusb_exit(NULL);

+ 6 - 3
miner.h

@@ -401,6 +401,8 @@ struct cgpu_info {
 	uint32_t nonces;
 	bool nonce_range;
 	bool polling;
+#endif
+#if defined(USE_BITFORCE) || defined(USE_ICARUS)
 	bool flash_led;
 #endif
 	void *cgpu_data;
@@ -442,9 +444,9 @@ struct cgpu_info {
 	size_t opt_tc, thread_concurrency;
 	size_t shaders;
 #endif
-	struct timeval tv_gpustart;;
-	struct timeval tv_gpuend;
-	double gpu_us_average;
+	struct timeval tv_gpustart;
+	struct timeval tv_gpumid;
+	int intervals, hit;
 #endif
 
 	bool new_work;
@@ -528,6 +530,7 @@ extern int thr_info_create(struct thr_info *thr, pthread_attr_t *attr, void *(*s
 extern void thr_info_cancel(struct thr_info *thr);
 extern void thr_info_freeze(struct thr_info *thr);
 extern void nmsleep(unsigned int msecs);
+extern double us_tdiff(struct timeval *end, struct timeval *start);
 extern void rename_thr(const char* name);
 extern double tdiff(struct timeval *end, struct timeval *start);
 

+ 6 - 0
util.c

@@ -762,6 +762,12 @@ void nmsleep(unsigned int msecs)
 	} while (ret == -1 && errno == EINTR);
 }
 
+/* Returns the microseconds difference between end and start times as a double */
+double us_tdiff(struct timeval *end, struct timeval *start)
+{
+	return end->tv_sec * 1000000 + end->tv_usec - start->tv_sec * 1000000 - start->tv_usec;
+}
+
 void rename_thr(const char* name) {
 #if defined(PR_SET_NAME)
 	// Only the first 15 characters are used (16 - NUL terminator)