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_LDFLAGS	= $(PTHREAD_FLAGS)
 bfgminer_LDADD	= $(DLOPEN_FLAGS) @LIBCURL_LIBS@ @JANSSON_LIBS@ @PTHREAD_LIBS@ \
 bfgminer_LDADD	= $(DLOPEN_FLAGS) @LIBCURL_LIBS@ @JANSSON_LIBS@ @PTHREAD_LIBS@ \
 		  @NCURSES_LIBS@ @PDCURSES_LIBS@ @WS2_LIBS@ \
 		  @NCURSES_LIBS@ @PDCURSES_LIBS@ @WS2_LIBS@ \
-		  @TIMER_LIBS@ \
 		  @UDEV_LIBS@ @USB_LIBS@ \
 		  @UDEV_LIBS@ @USB_LIBS@ \
 		  @MATH_LIBS@ lib/libgnu.a ccan/libccan.a
 		  @MATH_LIBS@ lib/libgnu.a ccan/libccan.a
 bfgminer_CPPFLAGS = -I$(top_builddir)/lib -I$(top_srcdir)/lib
 bfgminer_CPPFLAGS = -I$(top_builddir)/lib -I$(top_srcdir)/lib

+ 1 - 5
configure.ac

@@ -69,7 +69,6 @@ USB_LIBS=""
 USB_FLAGS=""
 USB_FLAGS=""
 DLOPEN_FLAGS="-ldl"
 DLOPEN_FLAGS="-ldl"
 WS2_LIBS=""
 WS2_LIBS=""
-TIMER_LIBS=""
 MATH_LIBS="-lm"
 MATH_LIBS="-lm"
 
 
 case $target in
 case $target in
@@ -88,7 +87,6 @@ case $target in
 	PTHREAD_FLAGS=""
 	PTHREAD_FLAGS=""
 	DLOPEN_FLAGS=""
 	DLOPEN_FLAGS=""
 	WS2_LIBS="-lws2_32"
 	WS2_LIBS="-lws2_32"
-	TIMER_LIBS="-lwinmm"
 	;;
 	;;
   *-*-mingw*)
   *-*-mingw*)
     have_x86_64=false
     have_x86_64=false
@@ -96,7 +94,6 @@ case $target in
     PTHREAD_FLAGS=""
     PTHREAD_FLAGS=""
     DLOPEN_FLAGS=""
     DLOPEN_FLAGS=""
     WS2_LIBS="-lws2_32"
     WS2_LIBS="-lws2_32"
-	TIMER_LIBS="-lwinmm"
     ;;
     ;;
   *-*-cygwin*)
   *-*-cygwin*)
 	have_cygwin=true
 	have_cygwin=true
@@ -416,7 +413,6 @@ AC_SUBST(NCURSES_CPPFLAGS)
 AC_SUBST(NCURSES_LIBS)
 AC_SUBST(NCURSES_LIBS)
 AC_SUBST(PDCURSES_LIBS)
 AC_SUBST(PDCURSES_LIBS)
 AC_SUBST(WS2_LIBS)
 AC_SUBST(WS2_LIBS)
-AC_SUBST(TIMER_LIBS)
 AC_SUBST(MATH_LIBS)
 AC_SUBST(MATH_LIBS)
 AC_SUBST(UDEV_LIBS)
 AC_SUBST(UDEV_LIBS)
 AC_SUBST(USB_LIBS)
 AC_SUBST(USB_LIBS)
@@ -509,7 +505,7 @@ echo "Compilation............: make (or gmake)"
 echo "  CPPFLAGS.............: $CPPFLAGS $NCURSES_CPPFLAGS"
 echo "  CPPFLAGS.............: $CPPFLAGS $NCURSES_CPPFLAGS"
 echo "  CFLAGS...............: $CFLAGS"
 echo "  CFLAGS...............: $CFLAGS"
 echo "  LDFLAGS..............: $LDFLAGS $PTHREAD_FLAGS $USB_FLAGS"
 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
 echo "Installation...........: make install (as root if needed, with 'su' or 'sudo')"
 echo "Installation...........: make install (as root if needed, with 'su' or 'sudo')"
 echo "  prefix...............: $prefix"
 echo "  prefix...............: $prefix"

+ 25 - 47
driver-opencl.c

@@ -800,21 +800,6 @@ struct cgpu_info *cpus;
 
 
 #ifdef HAVE_OPENCL
 #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.
 /* 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
  * 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 */
  * 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];
 	struct cgpu_info *cgpu = &gpus[gpu];
 	int i;
 	int i;
-#ifdef WIN32
-	bool any_dynamic = false;
-#endif
 
 
 	for (i = 1; i < cgpu->threads; i++) {
 	for (i = 1; i < cgpu->threads; i++) {
 		struct thr_info *thr = &thr_info[i];
 		struct thr_info *thr = &thr_info[i];
 
 
-#ifdef WIN32
-		if (cgpu->dynamic)
-			any_dynamic = true;
-#endif
-
 		if (!thr->pause && cgpu->dynamic) {
 		if (!thr->pause && cgpu->dynamic) {
 			applog(LOG_WARNING, "Disabling extra threads due to dynamic mode.");
 			applog(LOG_WARNING, "Disabling extra threads due to dynamic mode.");
 			applog(LOG_WARNING, "Tune dynamic intensity with --gpu-dyninterval");
 			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)
 		if (!cgpu->dynamic && cgpu->deven != DEV_DISABLED)
 			tq_push(thr->q, &ping);
 			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];
 	_clState *clState = clStates[thr_id];
 	const cl_kernel *kernel = &clState->kernel;
 	const cl_kernel *kernel = &clState->kernel;
 	const int dynamic_us = opt_dynamic_interval * 1000;
 	const int dynamic_us = opt_dynamic_interval * 1000;
+	struct timeval tv_gpuend;
 
 
 	cl_int status;
 	cl_int status;
 	size_t globalThreads[1];
 	size_t globalThreads[1];
@@ -1788,7 +1752,17 @@ static int64_t opencl_scanhash(struct thr_info *thr, struct work *work,
 		clFinish(clState->commandQueue);
 		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]);
 	status = thrdata->queue_kernel_parameters(clState, &work->blk, globalThreads[0]);
 	if (unlikely(status != CL_SUCCESS)) {
 	if (unlikely(status != CL_SUCCESS)) {
@@ -1818,26 +1792,30 @@ static int64_t opencl_scanhash(struct thr_info *thr, struct work *work,
 	}
 	}
 
 
 	if (gpu->dynamic) {
 	if (gpu->dynamic) {
-		struct timeval diff;
-		suseconds_t gpu_us;
+		double gpu_us;
 
 
 		clFinish(clState->commandQueue);
 		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
 			/* Try to not let the GPU be out for longer than
 			 * opt_dynamic_interval in ms, but increase
 			 * opt_dynamic_interval in ms, but increase
 			 * intensity when the system is idle in dynamic mode */
 			 * 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)
 				if (gpu->intensity > MIN_INTENSITY)
 					--gpu->intensity;
 					--gpu->intensity;
-			} else if (gpu->gpu_us_average < dynamic_us / 2) {
+			} else if (gpu_us < dynamic_us / 2) {
 				if (gpu->intensity < MAX_INTENSITY)
 				if (gpu->intensity < MAX_INTENSITY)
 					++gpu->intensity;
 					++gpu->intensity;
 			}
 			}
+			gpu->intervals = gpu->hit = 0;
 		}
 		}
 	}
 	}
 
 

+ 0 - 1
miner.c

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

+ 4 - 3
miner.h

@@ -430,9 +430,9 @@ struct cgpu_info {
 	size_t opt_tc, thread_concurrency;
 	size_t opt_tc, thread_concurrency;
 	size_t shaders;
 	size_t shaders;
 #endif
 #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
 #endif
 
 
 	bool new_work;
 	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_cancel(struct thr_info *thr);
 extern void thr_info_freeze(struct thr_info *thr);
 extern void thr_info_freeze(struct thr_info *thr);
 extern void nmsleep(unsigned int msecs);
 extern void nmsleep(unsigned int msecs);
+extern double us_tdiff(struct timeval *end, struct timeval *start);
 extern void rename_thr(const char* name);
 extern void rename_thr(const char* name);
 extern double tdiff(struct timeval *end, struct timeval *start);
 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);
 	} 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) {
 void rename_thr(const char* name) {
 #if defined(PR_SET_NAME)
 #if defined(PR_SET_NAME)
 	// Only the first 15 characters are used (16 - NUL terminator)
 	// Only the first 15 characters are used (16 - NUL terminator)