Browse Source

Update to cgminer's newer dynamic intensity algorithm

Old one doesn't seem to work right anymore, and nobody cares to maintain it
Luke Dashjr 13 years ago
parent
commit
9716613b17
6 changed files with 36 additions and 57 deletions
  1. 0 1
      Makefile.am
  2. 1 5
      configure.ac
  3. 25 47
      driver-opencl.c
  4. 0 1
      miner.c
  5. 4 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"
     ;;
   *-*-cygwin*)
 	have_cygwin=true
@@ -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;
 		}
 	}
 

+ 0 - 1
miner.c

@@ -6111,7 +6111,6 @@ static void clean_up(void)
 {
 #ifdef HAVE_OPENCL
 	clear_adl(nDevs);
-	opencl_dynamic_cleanup();
 #endif
 #ifdef HAVE_LIBUSB
         libusb_exit(NULL);

+ 4 - 3
miner.h

@@ -430,9 +430,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;
@@ -516,6 +516,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

@@ -753,6 +753,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)