Browse Source

opencl: Store oclthreads and only convert to/from intensity numbers when dealing with external interfaces

Luke Dashjr 12 years ago
parent
commit
27ce457591
5 changed files with 53 additions and 38 deletions
  1. 1 1
      api.c
  2. 4 0
      compat.h
  3. 6 0
      configure.ac
  4. 38 36
      driver-opencl.c
  5. 4 1
      driver-opencl.h

+ 1 - 1
api.c

@@ -2679,7 +2679,7 @@ static void gpuintensity(struct io_data *io_data, __maybe_unused SOCKETTYPE c, c
 		if (data->dynamic)
 			strcpy(intensitystr, DYNAMIC);
 		else
-			snprintf(intensitystr, sizeof(intensitystr), "%d", data->intensity);
+			snprintf(intensitystr, sizeof(intensitystr), "%g", oclthreads_to_intensity(data->oclthreads, !opt_scrypt));
 	}
 	else
 	{

+ 4 - 0
compat.h

@@ -185,6 +185,10 @@ typedef long suseconds_t;
 
 #endif /* WIN32 */
 
+#ifndef HAVE_LOG2
+#	define log2(n)  (log(n) / log(2))
+#endif
+
 #ifndef HAVE_PTHREAD_CANCEL
 
 // Bionic (Android) is intentionally missing pthread_cancel, so it is implemented using pthread_kill (handled in util.c)

+ 6 - 0
configure.ac

@@ -1547,6 +1547,12 @@ AC_TRY_COMPILE([
 ])
 
 
+save_LIBS="$LIBS"
+LIBS="$LIBS $MATH_LIBS"
+AC_CHECK_FUNCS([log2])
+LIBS="$save_LIBS"
+
+
 if test "x$prefix" = xNONE; then
 	prefix=/usr/local
 fi

+ 38 - 36
driver-opencl.c

@@ -22,6 +22,7 @@
 #include <windows.h>
 #endif
 
+#include <math.h>
 #include <string.h>
 #include <stdbool.h>
 #include <stdint.h>
@@ -533,6 +534,22 @@ _SET_INT_LIST(temp_overheat, (v >=     0 && v <   200), adl.overtemp )
 #endif
 
 #ifdef HAVE_OPENCL
+// SHA256d "intensity" has an artificial offset of -15
+double oclthreads_to_intensity(const unsigned long oclthreads, const bool is_sha256d)
+{
+	double intensity = log2(oclthreads);
+	if (is_sha256d)
+		intensity -= 15.;
+	return intensity;
+}
+
+unsigned long intensity_to_oclthreads(double intensity, const bool is_sha256d)
+{
+	if (is_sha256d)
+		intensity += 15;
+	return pow(2, intensity);
+}
+
 static
 bool _set_intensity(struct cgpu_info * const cgpu, const char * const _val)
 {
@@ -541,11 +558,11 @@ bool _set_intensity(struct cgpu_info * const cgpu, const char * const _val)
 		data->dynamic = true;
 	else
 	{
-		const int v = atoi(_val);
+		const double v = atof(_val);
 		if (v < MIN_INTENSITY || v > MAX_GPU_INTENSITY)
 			return false;
 		data->dynamic = false;
-		data->intensity = v;
+		data->oclthreads = intensity_to_oclthreads(v, !opt_scrypt);
 	}
 	pause_dynamic_threads(cgpu->device_id);
 	return true;
@@ -575,7 +592,7 @@ void write_config_opencl(FILE * const fcfg)
 			if (data->dynamic)
 				fputc('d', fcfg);
 			else
-				fprintf(fcfg, "%d", data->intensity);
+				fprintf(fcfg, "%g", oclthreads_to_intensity(data->oclthreads, !opt_scrypt));
 		}
 		fputs("\",\n\"vectors\" : \"", fcfg);
 		for(i = 0; i < nDevs; i++)
@@ -772,7 +789,7 @@ void opencl_wlogprint_status(struct cgpu_info *cgpu)
 	char logline[255];
 	strcpy(logline, ""); // In case it has no data
 	
-	tailsprintf(logline, sizeof(logline), "I:%s%d  ", (data->dynamic ? "d" : ""), data->intensity);
+	tailsprintf(logline, sizeof(logline), "I:%s%g  ", (data->dynamic ? "d" : ""), oclthreads_to_intensity(data->oclthreads, !opt_scrypt));
 #ifdef HAVE_ADL
 	if (data->has_adl) {
 		int engineclock = 0, memclock = 0, activity = 0, fanspeed = 0, fanpercent = 0, powertune = 0;
@@ -863,7 +880,6 @@ const char *opencl_tui_handle_choice(struct cgpu_info *cgpu, int input)
 	{
 		case 'i': case 'I':
 		{
-			int intensity;
 			char *intvar;
 
 			if (opt_scrypt) {
@@ -883,13 +899,9 @@ const char *opencl_tui_handle_choice(struct cgpu_info *cgpu, int input)
 				free(intvar);
 				return "Dynamic mode enabled\n";
 			}
-			intensity = atoi(intvar);
-			free(intvar);
-			if (intensity < MIN_INTENSITY || intensity > MAX_INTENSITY)
+			if (!_set_intensity(cgpu, intvar))
 				return "Invalid intensity (out of range)\n";
-			data->dynamic = false;
-			data->intensity = intensity;
-			pause_dynamic_threads(cgpu->device_id);
+			free(intvar);
 			return "Intensity changed\n";
 		}
 		case 'r': case 'R':
@@ -1193,25 +1205,6 @@ cl_int queue_scrypt_kernel(_clState * const clState, struct work * const work, _
 	return status;
 }
 #endif
-
-static void set_threads_hashes(unsigned int vectors,int64_t *hashes, size_t *globalThreads,
-			       unsigned int minthreads, __maybe_unused int *intensity)
-{
-	unsigned int threads = 0;
-
-	while (threads < minthreads) {
-		threads = 1 << ((opt_scrypt ? 0 : 15) + *intensity);
-		if (threads < minthreads) {
-			if (likely(*intensity < MAX_INTENSITY))
-				(*intensity)++;
-			else
-				threads = minthreads;
-		}
-	}
-
-	*globalThreads = threads;
-	*hashes = threads * vectors;
-}
 #endif /* HAVE_OPENCL */
 
 
@@ -1495,7 +1488,7 @@ get_opencl_api_extra_device_status(struct cgpu_info *gpu)
 	if (data->dynamic)
 		strcpy(intensity, "D");
 	else
-		sprintf(intensity, "%d", data->intensity);
+		sprintf(intensity, "%g", oclthreads_to_intensity(data->oclthreads, !opt_scrypt));
 	root = api_add_string(root, "Intensity", intensity, true);
 
 	return root;
@@ -1690,17 +1683,26 @@ static int64_t opencl_scanhash(struct thr_info *thr, struct work *work,
 		cgtime(&tv_gpuend);
 		gpu_us = us_tdiff(&tv_gpuend, &data->tv_gpustart) / data->intervals;
 		if (gpu_us > dynamic_us) {
-			if (data->intensity > MIN_INTENSITY)
-				--data->intensity;
+			const unsigned long min_oclthreads = intensity_to_oclthreads(MIN_INTENSITY, !opt_scrypt);
+			data->oclthreads /= 2;
+			if (data->oclthreads < min_oclthreads)
+				data->oclthreads = min_oclthreads;
 		} else if (gpu_us < dynamic_us / 2) {
-			if (data->intensity < MAX_INTENSITY)
-				++data->intensity;
+			const unsigned long max_oclthreads = intensity_to_oclthreads(MAX_INTENSITY, !opt_scrypt);
+			data->oclthreads *= 2;
+			if (data->oclthreads > max_oclthreads)
+				data->oclthreads = max_oclthreads;
 		}
 		memcpy(&(data->tv_gpustart), &tv_gpuend, sizeof(struct timeval));
 		data->intervals = 0;
 	}
 
-	set_threads_hashes(clState->vwidth, &hashes, globalThreads, localThreads[0], &data->intensity);
+	if (data->oclthreads < localThreads[0])
+		data->oclthreads = localThreads[0];
+	globalThreads[0] = data->oclthreads;
+	hashes = globalThreads[0];
+	hashes *= clState->vwidth;
+	
 	if (hashes > gpu->max_hashes)
 		gpu->max_hashes = hashes;
 

+ 4 - 1
driver-opencl.h

@@ -14,7 +14,7 @@ struct opencl_device_data {
 	bool mapped;
 	int virtual_gpu;
 	int virtual_adl;
-	int intensity;
+	unsigned long oclthreads;
 	bool dynamic;
 	
 	cl_uint vwidth;
@@ -49,6 +49,9 @@ struct opencl_device_data {
 #endif
 };
 
+extern double oclthreads_to_intensity(unsigned long oclthreads, bool is_sha256d);
+extern unsigned long intensity_to_oclthreads(double intensity, bool is_sha256d);
+
 struct opencl_work_data {
 	cl_uint ctx_a; cl_uint ctx_b; cl_uint ctx_c; cl_uint ctx_d;
 	cl_uint ctx_e; cl_uint ctx_f; cl_uint ctx_g; cl_uint ctx_h;