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