svn commit: r211147 - user/des/phybs

Dag-Erling Smorgrav des at FreeBSD.org
Tue Aug 10 14:44:21 UTC 2010


Author: des
Date: Tue Aug 10 14:44:20 2010
New Revision: 211147
URL: http://svn.freebsd.org/changeset/base/211147

Log:
  This is a small program that runs a series of performance tests
  designed to reveal the physical block size of a disk.  It performs a
  series of staggered reads and / or writes of different lengths at
  different alignments.  The idea is that a disk that has a large
  physical blocksize but simulates a smaller one will perform poorly,
  due to read-modify-write, except when both the I/O size and the offset
  are multiples of the physical block size.
  
  The program supports read-only, write-only and read-write tests.  The
  default is write-only.  A read-write test is probably not very useful,
  because it primes the cache in cases where the disk would actually
  perform an extra read.  A read-only test is useless except as a quick
  way to verify that the program works.
  
  Note that the program currently assumes a logical block size of 512
  bytes and that the parameters (size range, interval and iterations)
  are hardcoded.

Added:
  user/des/phybs/
  user/des/phybs/Makefile   (contents, props changed)
  user/des/phybs/phybs.c   (contents, props changed)

Added: user/des/phybs/Makefile
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/des/phybs/Makefile	Tue Aug 10 14:44:20 2010	(r211147)
@@ -0,0 +1,9 @@
+# $FreeBSD$
+
+PROG	 = phybs
+CSTD	?= c99
+WARNS	?= 6
+MAN	 = # none
+
+.include "../Makefile.inc"
+.include <bsd.prog.mk>

Added: user/des/phybs/phybs.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/des/phybs/phybs.c	Tue Aug 10 14:44:20 2010	(r211147)
@@ -0,0 +1,145 @@
+/*-
+ * Copyright (c) 2010 Dag-Erling Coïdan Smørgrav
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer
+ *    in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/time.h>
+
+#include <err.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#define MINSIZE		512
+#define MAXSIZE		8192
+#define STEP		MAXSIZE
+#define COUNT		65536
+
+static int opt_r = 0;
+static int opt_w = 1;
+
+static void
+scan(int fd, size_t size, off_t offset, off_t step, unsigned int count)
+{
+	struct timeval t0, t1;
+	unsigned long usec;
+	ssize_t rlen, wlen;
+	char *buf;
+
+	printf("%8u%8lu%8lu%8lu", count, (unsigned long)size,
+	    (unsigned long)offset, (unsigned long)step);
+	fflush(stdout);
+	if ((buf = malloc(size)) == NULL)
+		err(1, "malloc()");
+	memset(buf, 0, size);
+	if (gettimeofday(&t0, NULL) == -1)
+		err(1, "gettimeofday()");
+	for (unsigned int i = 0; i < count; ++i, offset += step) {
+		if (opt_r) {
+			if (lseek(fd, offset, SEEK_SET) != offset)
+				err(1, "lseek(%lu)", (unsigned long)offset);
+			if ((rlen = read(fd, buf, size)) == -1)
+				err(1, "read(%lu)", (unsigned long)size);
+			if (rlen < (ssize_t)size)
+				errx(1, "short read: %ld < %lu",
+				    (long)rlen, (unsigned long)size);
+		}
+		if (opt_w) {
+			if (lseek(fd, offset, SEEK_SET) != offset)
+				err(1, "lseek(%lu)", (unsigned long)offset);
+			if ((wlen = write(fd, buf, size)) == -1)
+				err(1, "write(%lu)", (unsigned long)size);
+			if (wlen < (ssize_t)size)
+				errx(1, "short write: %ld < %lu",
+				    (long)wlen, (unsigned long)size);
+		}
+	}
+	if (gettimeofday(&t1, NULL) == -1)
+		err(1, "gettimeofday()");
+	usec = t1.tv_sec * 1000000 + t1.tv_usec;
+	usec -= t0.tv_sec * 1000000 + t0.tv_usec;
+	printf("%12lu%8lu%8lu\n", usec / 1000,
+	    count * 1000000 / usec,
+	    count * size * 1000000 / 1024 / usec);
+	free(buf);
+}
+
+static void
+usage(void)
+{
+
+	fprintf(stderr, "usage: phybs [-R | -r] [-W | -w] device\n");
+	exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+	char *device;
+	int fd, opt;
+
+	while ((opt = getopt(argc, argv, "RrWw")) != -1)
+		switch (opt) {
+		case 'R':
+			opt_r = 0;
+			break;
+		case 'r':
+			opt_r = 1;
+			break;
+		case 'W':
+			opt_w = 0;
+			break;
+		case 'w':
+			opt_w = 1;
+			break;
+		default:
+			usage();
+		}
+
+	argc -= optind;
+	argv += optind;
+
+	if (argc != 1)
+		usage();
+
+	if (!opt_r && !opt_w)
+		opt_r = opt_w = 1;
+
+	device = argv[0];
+	if ((fd = open(device, opt_w ? O_RDWR : O_RDONLY)) == -1)
+		err(1, "open(%s)", device);
+	printf("%8s%8s%8s%8s%12s%8s%8s\n",
+	    "count", "size", "offset", "step",
+	    "msec", "tps", "kBps");
+	for (size_t size = MINSIZE; size <= MAXSIZE; size *= 2)
+		for (off_t offset = 0; offset < (off_t)size; offset += 512)
+			scan(fd, size, offset, STEP, COUNT);
+	close(fd);
+	exit(0);
+}


More information about the svn-src-user mailing list