Browse Source

Merge commit '8745ba1' into bfgminer-2.6.x

Conflicts:
	miner.h
	util.c
Luke Dashjr 13 years ago
parent
commit
4051ca68cd
3 changed files with 28 additions and 10 deletions
  1. 18 8
      driver-opencl.c
  2. 4 2
      miner.h
  3. 6 0
      util.c

+ 18 - 8
driver-opencl.c

@@ -1778,6 +1778,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_bool blocking;
 
 	cl_int status;
@@ -1796,13 +1797,17 @@ static int64_t opencl_scanhash(struct thr_info *thr, struct work *work,
 		clFinish(clState->commandQueue);
 
 	if (gpu->dynamic) {
-		struct timeval diff;
-		suseconds_t gpu_us;
-
-		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)) {
+		double gpu_us;
+
+		/* 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;
 			gpu->gpu_us_average = (gpu->gpu_us_average + gpu_us * 0.63) / 1.63;
 
 			/* Try to not let the GPU be out for longer than 
@@ -1815,6 +1820,7 @@ static int64_t opencl_scanhash(struct thr_info *thr, struct work *work,
 				if (gpu->intensity < MAX_INTENSITY)
 					++gpu->intensity;
 			}
+			gpu->intervals = gpu->hit = 0;
 		}
 	}
 	set_threads_hashes(clState->vwidth, &threads, &hashes, globalThreads,
@@ -1850,7 +1856,11 @@ static int64_t opencl_scanhash(struct thr_info *thr, struct work *work,
 			clFinish(clState->commandQueue);
 	}
 
-	gettimeofday(&gpu->tv_gpustart, NULL);
+	gettimeofday(&gpu->tv_gpumid, NULL);
+	if (!gpu->intervals) {
+		gpu->tv_gpustart.tv_sec = gpu->tv_gpumid.tv_sec;
+		gpu->tv_gpustart.tv_usec = gpu->tv_gpumid.tv_usec;
+	}
 
 	if (clState->goffset) {
 		size_t global_work_offset[1];

+ 4 - 2
miner.h

@@ -404,9 +404,10 @@ struct cgpu_info {
 	int opt_tc, thread_concurrency;
 	int shaders;
 #endif
-	struct timeval tv_gpustart;;
-	struct timeval tv_gpuend;
+	struct timeval tv_gpustart;
+	struct timeval tv_gpumid;
 	double gpu_us_average;
+	int intervals, hit;
 #endif
 
 	float temp;
@@ -480,6 +481,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);
 
 struct string_elist {

+ 6 - 0
util.c

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