Subject: pkg/17941: bugs in hbench
To: None <gnats-bugs@gnats.netbsd.org>
From: None <dsl@l8s.co.uk>
List: netbsd-bugs
Date: 08/14/2002 20:26:41
>Number:         17941
>Category:       pkg
>Synopsis:       bugs in hbench
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    pkg-manager
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Aug 14 12:24:00 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator:     David Laight
>Release:        NetBSD 1.6F
>Organization:
no
>Environment:
System: NetBSD snowdrop 1.6F NetBSD 1.6F (GENERIC) #146: Tue Aug 13 09:17:25 BST 2002
dsl@snowdrop:/oldroot/usr/bsd-current/src/sys/arch/i386/compile/GENERIC i386
Architecture: i386
Machine: i386
>Description:
	hbench-OS 1.0 core dumps in the file delete test when reversing
	the list of files.

	Additionally the performance of the tests can be improved considerably
	by optimising the code that determines the number of iterations
	required.  Changing this code doesn't affect the benchmark figures.
	The changes reduce the time for 1 pass from just over an hour
	to under 30 minutes.  Mainly by stopping it taking 2 seconds to
	find out how many times to run a test to get it to take 1 second.

>How-To-Repeat:
>Fix:
	Apply the following patches:

	The core dump is a trivial coding bug.  Apply following diff:
diff -ur ./src/lat_fs.c work/hbench-OS/src/lat_fs.c
--- ./src/lat_fs.c      Fri Jun 27 01:34:38 1997
+++ work/hbench-OS/src/lat_fs.c       Wed Aug 14 12:48:11 2002
@@ -229,8 +229,8 @@
 	if (deldir == DEL_REVERSE) {
 		for (i = 0; i < (num_iter +1)/2; i++) {
 			/* swap(filenames[i],filenames[numfiles - i]); */
-			tmp = filenames[num_iter - i];
-			filenames[num_iter - i] = filenames[i];
+			tmp = filenames[num_iter - 1 - i];
+			filenames[num_iter - 1 - i] = filenames[i];
 			filenames[i] = tmp;
 		}
 	} else if (deldir == DEL_PSEUDORANDOM) {

==================================================================

	This change speeds up the time taken to work out how many
	iterations to run by applying a little linearity.

diff -ur ./src/timing.c work/hbench-OS/src/timing.c
--- ./src/timing.c      Fri Jun 27 04:52:29 1997
+++ work/hbench-OS/src/timing.c       Wed Aug 14 14:11:22 2002
@@ -201,19 +201,24 @@
 #ifdef DEBUG
 	printf(">> %d iteration gives %f seconds\n",num,((float)rtntime)*clkmul/1000000.);
 #endif
-	while ((time = ((float)rtntime)*clkmul) < 1000000.) {
-		/* while less than one second */
-		num <<= 1;
+	while ((time = ((float)rtntime)*clkmul) < 1000000./16) {
+		/* while less than 1/16 second */
+		num <<= 2;
 		if ((*workfn)(num, &rtntime) != 0) {
 			num >>= 1;
 #ifdef DEBUG
-			printf(">> backing off\n");
+			printf(">> backing off to %d iterations\n", num);
 #endif
-			break;
+			return num;
 		}
 #ifdef DEBUG
 		printf(">> %d iterations gives %f seconds\n",num,((float)rtntime)*clkmul/1000000.);
 #endif
+	}
+	while (time < 1000000.) {
+		/* while less than one second */
+		num <<= 1;
+		time *= 2;
 	}
 #ifdef DEBUG
 	printf(">> Choosing %d iterations\n",num);

==================================================================

	Speed up lat_ctx and lat_ctx2 - the amount of the value
	subtracted isn't critical when trying to get niter:

diff -ur ./src/lat_ctx.c work/hbench-OS/src/lat_ctx.c
--- ./src/lat_ctx.c     Fri Jun 27 01:34:37 1997
+++ work/hbench-OS/src/lat_ctx.c      Wed Aug 14 15:18:42 2002
@@ -63,6 +63,7 @@
 pid_t	pids[MAX_PROCS];	/* process ID's */
 int	*pbuffer;		/* memory buffer for procs to sum */
 int	*locdata;		/* proc's memory buffer for procs to sum */
+int	initial_niter;		/* number of iterations we were requesed to do */
 
 int
 main(ac, av)
@@ -84,7 +85,7 @@
 	}
 
 	/* parse command line parameters */
-	niter = atoi(av[1]);
+	initial_niter = niter = atoi(av[1]);
 	sprocs = parse_bytes(av[2]);
 	nprocs = atoi(av[3]);
 	
@@ -275,6 +276,12 @@
 {
 	int 	i;
 	clk_t	val;
+
+	if (initial_niter == 0) {
+		/* We are only trying to find how many times to run the test */
+		do_overhead1(num_iter >> 1, t);
+		return 0;
+	}
 
 	centeravg_reset(OVERHEADAVG_LOOPS, OVERHEADAVG_TAILS);
 
diff -ur ./src/lat_ctx2.c work/hbench-OS/src/lat_ctx2.c
--- ./src/lat_ctx2.c    Fri Jun 27 01:34:37 1997
+++ work/hbench-OS/src/lat_ctx2.c     Wed Aug 14 15:20:11 2002
@@ -63,6 +63,7 @@
 pid_t	pids[MAX_PROCS];	/* process ID's */
 int	*pbuffer;		/* memory buffer for procs to sum */
 int	*locdata;		/* proc's memory buffer for procs to sum */
+int	initial_niter;		/* number of iterations we were requesed to do */
 
 int
 main(ac, av)
@@ -84,7 +85,7 @@
 	}
 
 	/* parse command line parameters */
-	niter = atoi(av[1]);
+	initial_niter = niter = atoi(av[1]);
 	sprocs = parse_bytes(av[2]);
 	nprocs = atoi(av[3]);
 	
@@ -250,6 +251,12 @@
 {
 	int 	i;
 	clk_t	val;
+
+	if (initial_niter == 0) {
+		/* We are only trying to find how many times to run the test */
+		do_overhead1(num_iter >> 1, t);
+		return 0;
+	}
 
 	centeravg_reset(OVERHEADAVG_LOOPS, OVERHEADAVG_TAILS);
 
==================================================================

	The bw_pipe test sleeps for a second each time it is run.
	This costs several seconds....
	Maybe calling poll(0,0,1) twice will give an adequate delay.
	The fix below pulls 'bufsize' of data through the pipe
	before starting the measurement.
	NB this file already has a patch, this diff is against the
	official source file.

diff -ur ./src/bw_pipe.c work/hbench-OS/src/bw_pipe.c
--- ./src/bw_pipe.c	Fri Jun 27 01:34:33 1997
+++ work/hbench-OS/src/bw_pipe.c	Wed Aug 14 15:31:31 2002
@@ -134,7 +134,7 @@
 	}
 
 	/* Amount to transfer */
-	todo = XFERUNIT * num_iter;
+	todo = XFERUNIT * num_iter + bufsize;
 	
 	/* Allocate buffer */
 	buf = (char *) malloc(bufsize);
@@ -147,6 +147,8 @@
 	/* Spawn off a writer, then time the read */
 	switch (fork()) {
 	case 0:			/* writer */
+		close(pipes[0]);
+
 		while ((done < todo) &&
 		       ((n = write(pipes[1], buf, bufsize)) > 0))
 			done += n;
@@ -159,8 +161,12 @@
 		/*NOTREACHED*/
 		
 	default:		/* reader */
+		close(pipes[1]);
+
 		/* wait for writer */
-		sleep(1);
+		while ((done < bufsize) &&
+		       ((n = read(pipes[0], buf, bufsize - done)) > 0))
+			done += n;
 		
 		start();	/* start timing */
 		while ((done < todo) &&
@@ -168,6 +174,7 @@
 			done += n;
 		*t = stop();	/* stop timing */
 
+		close(pipes[0]);
 		wait(&termstat); /* wait for writer to exit */
 	}
 	
>Release-Note:
>Audit-Trail:
>Unformatted: