no battery = no cache. Performance is abysmal without.
On Tue, Aug 22, 2006 at 02:17:35AM +0200, Robert Urban wrote:
> Hi Folks,
>
> using a simple test program to write sequential blocks to a file, optionally
> opening with O_SYNC, I've tested write performance to a MegaRAID logical
> drive consisting of a RAID-5 set of 4 72GB HP Ultra320 disks and to a RAID-0
> drive consisting of a single 300GB HP Ultra320 disk. The controller
> has 128MB of cache, but I do not have a battery, so cache write policy
> is write-through. The kernel is the "bsd", and not "bsd.mp", but it makes
> no difference. I've tried both.
>
> All tests performed with O_SYNC, to avoid bufcache interaction.
>
> The performance, at least to my perhaps naive eyes, seems abysmal. I'm
> getting
> 1.2MB/sec on the RAID-5 logical drive.
>
> It doesn't matter what blocksize I choose, 32k, 64k, 128k, 256k. The
> chunksize
> on the logical drive is the default, 64k.
>
> On the single HP 300GB Ultra320 RAID-0 drive write performance is also bad:
> 1.7MB/sec.
>
> The systems is (in case you hadn't already guessed) a Compaq ProLiant DL380-G2
> with 1GB main memory and dual 1266MHz CPUs. I will attach dmesg, my test
> program, and the output of "bioctl -iv ami0" below.
>
> I can't imagine the MegaRAID controller is this slow. Any suggestions?
>
> Rob Urban
>
> dmesg:
> ---------------------------------------------------------------
> OpenBSD 3.9 (GENERIC) #617: Thu Mar 2 02:26:48 MST 2006
> [EMAIL PROTECTED]:/usr/src/sys/arch/i386/compile/GENERIC
> cpu0: Intel(R) Pentium(R) III CPU family 1266MHz ("GenuineIntel" 686-class)
> 1.27 GHz
> cpu0:
> FPU,V86,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,M
> MX,FXSR,SSE
> real mem = 1073307648 (1048152K)
> avail mem = 972660736 (949864K)
> using 4278 buffers containing 53768192 bytes (52508K) of memory
> mainbus0 (root)
> bios0 at mainbus0: AT/286+(00) BIOS, date 12/31/99, BIOS32 rev. 0 @ 0xf0000
> pcibios0 at bios0: rev 2.1 @ 0xf0000/0x2000
> pcibios0: PCI BIOS has 9 Interrupt Routing table entries
> pcibios0: PCI Interrupt Router at 000:15:0 ("ServerWorks OSB4" rev 0x00)
> pcibios0: PCI bus #0 is the last bus
> bios0: ROM list: 0xc0000/0x8000 0xc8000/0x2600 0xee000/0x2000!
> cpu0 at mainbus0
> pci0 at mainbus0 bus 0: configuration mode 1 (no bios)
> pchb0 at pci0 dev 0 function 0 "ServerWorks CNB20HE Host" rev 0x23
> pci1 at pchb0 bus 1
> ppb0 at pci1 dev 3 function 0 "Intel i960 RP PCI-PCI" rev 0x05
> pci2 at ppb0 bus 2
> vga1 at pci2 dev 0 function 0 "ATI Mach64 GV" rev 0x7a
> wsdisplay0 at vga1 mux 1: console (80x25, vt100 emulation)
> wsdisplay0: screen 1-5 added (80x25, vt100 emulation)
> "Intel 80960RP ATU" rev 0x05 at pci1 dev 3 function 1 not configured
> pchb1 at pci0 dev 0 function 1 "ServerWorks CNB20HE Host" rev 0x01
> pchb2 at pci0 dev 0 function 2 "ServerWorks CNB20HE Host" rev 0x01
> pchb3 at pci0 dev 0 function 3 "ServerWorks CNB20HE Host" rev 0x01
> pci3 at pchb3 bus 7
> ami0 at pci3 dev 4 function 0 "Symbios Logic MegaRAID" rev 0x01: irq 3 Dell
> 518 64b/lhc
> ami0: FW 351X, BIOS v1.10, 128MB RAM
> ami0: 2 channels, 0 FC loops, 2 logical drives
> scsibus0 at ami0: 40 targets
> sd0 at scsibus0 targ 0 lun 0: <AMI, Host drive #00, > SCSI2 0/direct fixed
> sd0: 208110MB, 208110 cyl, 64 head, 32 sec, 512 bytes/sec, 426209280 sec total
> sd1 at scsibus0 targ 1 lun 0: <AMI, Host drive #01, > SCSI2 0/direct fixed
> sd1: 286080MB, 286080 cyl, 64 head, 32 sec, 512 bytes/sec, 585891840 sec total
> scsibus1 at ami0: 16 targets
> uk0 at scsibus1 targ 15 lun 0: <COMPAQ, PROLIANT 4L6I, 1.84> SCSI2
> 3/processor
> fixed
> uk0: unknown device
> scsibus2 at ami0: 16 targets
> "Compaq PCI Hotplug" rev 0x12 at pci3 dev 7 function 0 not configured
> fxp0 at pci0 dev 2 function 0 "Intel 8255x" rev 0x08, i82559: irq 5, address
> 00:08:02:8a:4b:fc
> inphy0 at fxp0 phy 1: i82555 10/100 PHY, rev. 4
> fxp1 at pci0 dev 4 function 0 "Intel 8255x" rev 0x08, i82559: irq 7, address
> 00:08:02:8a:4b:fb
> inphy1 at fxp1 phy 1: i82555 10/100 PHY, rev. 4
> "Compaq Netelligent ASMC" rev 0x00 at pci0 dev 6 function 0 not configured
> piixpm0 at pci0 dev 15 function 0 "ServerWorks OSB4" rev 0x51: SMBus disabled
> pciide0 at pci0 dev 15 function 1 "ServerWorks OSB4 IDE" rev 0x00: DMA
> atapiscsi0 at pciide0 channel 0 drive 0
> scsibus3 at atapiscsi0: 2 targets
> cd0 at scsibus3 targ 0 lun 0: <COMPAQ, CD-ROM SN-124, N102> SCSI0 5/cdrom
> removable
> cd0(pciide0:0:0): using PIO mode 4, DMA mode 2, Ultra-DMA mode 1
> ohci0 at pci0 dev 15 function 2 "ServerWorks OSB4/CSB5 USB" rev 0x04: irq 11,
> version 1.0, legacy support
> usb0 at ohci0: USB revision 1.0
> uhub0 at usb0
> uhub0: ServerWorks OHCI root hub, rev 1.00/1.00, addr 1
> uhub0: 4 ports with 4 removable, self powered
> isa0 at mainbus0
> isadma0 at isa0
> pckbc0 at isa0 port 0x60/5
> pckbd0 at pckbc0 (kbd slot)
> pckbc0: using irq 1 for kbd slot
> wskbd0 at pckbd0: console keyboard, using wsdisplay0
> pms0 at pckbc0 (aux slot)
> pckbc0: using irq 12 for aux slot
> wsmouse0 at pms0 mux 0
> pcppi0 at isa0 port 0x61
> midi0 at pcppi0: <PC speaker>
> spkr0 at pcppi0
> npx0 at isa0 port 0xf0/16: using exception 16
> pccom0 at isa0 port 0x3f8/8 irq 4: ns16550a, 16 byte fifo
> fdc0 at isa0 port 0x3f0/6 irq 6 drq 2
> fd0 at fdc0 drive 0: 1.44MB 80 cyl, 2 head, 18 sec
> biomask ef4d netmask efed ttymask ffef
> pctr: 686-class user-level performance counters enabled
> mtrr: Pentium Pro MTRR support
> uhub0: device problem, disabling port 1
> dkcsum: sd0 matches BIOS drive 0x80
> dkcsum: sd1 matches BIOS drive 0x81
> root on sd0a
> rootdev=0x400 rrootdev=0xd00 rawdev=0xd02
>
> write-test.c:
> * write-test.c
> *
> * write-test is meant to test simple writing performance to a *new*
> * file. Blocksize can be set, default is 128KB.
> *
> * Usage:
> *
> * This program performs tests on a *new* file. (it will truncate an
> * existing file.)
> *
> * Although performance results are returned when file-creation is finished,
> * they don't have any relevance for random writes. File-creation is
> * performed using an open(2) call.
> *
> * This program writes blocks of the specified block size, default=128KB.
> *
> * To perform a test:
> *
> * write-test -f <file-1>
> *
> * Compilation:
> *
> * cc -O4 -o write-test write-test.c
> *
> * Version: 1.0
> *
> * author: Robert Urban <[EMAIL PROTECTED]>
> *-----------------------------------------------------------------------*/
>
> #include <stdlib.h>
> #include <stdio.h>
> #include <unistd.h>
> #include <fcntl.h>
> #include <sys/stat.h>
> #include <sys/types.h>
> #include <signal.h>
> #include <time.h>
> #include <sys/time.h>
> #include <errno.h>
>
> #define KILOBYTE (1024)
> #define MEGABYTE (1024 * 1024)
> #define GIGABYTE (1024 * 1024 * 1024)
> #define DEF_BLOCKSIZE (128 * 1024)
> #define MAX_BLOCKSIZE (256 * 1024)
>
>
> /* prototypes */
> void handleSignal(int sig);
> float diff(struct timeval *start, struct timeval *end);
> void initChunk(char ch);
> void usage();
> void writeData();
>
>
> /* globals */
> int allrandom = 1;
> int debug = 0;
> long size = 128; /* 128 MB */
> char filename[128] = { NULL };
> int seconds = 60;
> int io_count = 0;
> float latency_cum = 0.0;
> int blocksize = DEF_BLOCKSIZE;
> long written = 0;
>
> struct timeval bm_start, bm_end;
> struct timeval io_start, io_end;
>
> char *chunk;
> int thefd;
> int blockcount;
> int f_sync = 0;
> int f_directio = 0;
>
> main(int argc, char *argv[]) {
> time_t tloc;
> char ran_args[32];
> int c, errflg = 0;
> struct stat statbuf;
> int num_files = 0;
> struct timeval tv;
>
> gettimeofday(&tv, NULL);
> srand48(tv.tv_usec);
>
> #define ARGS "hdDSf:s:b:"
>
> optarg = NULL;
> while (!errflg && ((c = getopt(argc, argv, ARGS)) != -1))
> switch (c) {
> case 'h':
> usage();
> exit(0);
> case 'b':
> blocksize = atoi(optarg) * KILOBYTE;
> break;
> case 's':
> /* size = atoi(optarg) * MEGABYTE; */
> size = atoi(optarg);
> break;
> case 'd':
> debug = 1;
> break;
> case 'S':
> f_sync = 1;
> break;
> case 'f':
> if (num_files == 1) {
> printf("you cannot specify more than 1
> file.\n");
> exit(1);
> }
> strcpy(filename, optarg);
> num_files++;
> break;
> default:
> printf("unrecognized option: [%c].\n", c);
> errflg++;
> usage();
> exit(-1);
> }
>
> chunk = (char *) malloc(MAX_BLOCKSIZE);
>
> if (num_files != 1) {
> printf("exactly 1 file must be specified using '-f'.\n");
> exit(1);
> }
>
> /* convert size to bytes */
> size *= MEGABYTE;
>
> initChunk('A');
>
> blockcount = size / blocksize;
>
> if (debug) {
> printf("SIZE : %ld\n", size);
> printf("BLOCKS : %d\n", blockcount);
> printf("BLKSIZ : %d\n", blocksize);
> printf("FILE : %s\n", filename);
> printf("SYNC : %s\n", f_sync ? "Yes" : "No");
> }
>
> if (filename == 0) {
> printf("must supply a file using \"-f <filename>\"\n");
> exit(-1);
> }
>
> signal(SIGINT, handleSignal);
> signal(SIGTERM, handleSignal);
> signal(SIGHUP, handleSignal);
> signal(SIGALRM, handleSignal);
>
> gettimeofday(&bm_start, NULL);
> writeData();
> handleSignal(0);
> }
>
> void usage() {
> printf("usage: write-test -f <file> [flags]\n");
> printf("\twhere flags are:\n");
> printf("\t-d turn on debug messages\n");
> printf("\t-S open output file with O_SYNC\n");
> printf("\t-s <size> specify size in Megebytes
> (default=100MB)\n");
> printf("\t-b <blocksize> specify blocksize in Kilobytes
> (default=128)\n");
> }
>
> void markStart()
> {
> gettimeofday(&io_start, NULL);
> }
>
> void markEnd()
> {
> float et;
> gettimeofday(&io_end, NULL);
>
> et = diff(&io_start, &io_end);
> latency_cum += et;
> if (debug) printf("latency: %.3f ms\n", et*1000);
> }
>
> void handleSignal(int sig) {
> float et;
> int index;
>
> gettimeofday(&bm_end, NULL);
> et = diff(&bm_start, &bm_end);
> printf("%d IOs in %.2f seconds, %.2f IOs/sec, %.2f MB/sec\n",
> io_count, et,
> io_count/et,
> ((float)written/et)/(float)MEGABYTE);
>
> printf("latency for %s: %.3f ms\n",
> filename,
> latency_cum/io_count*1000);
>
> close(thefd);
> exit(0);
> }
>
> void writeData() {
> int this_blocksize;
> int ret;
> /* int flags = O_CREAT|O_TRUNC|O_WRONLY|O_SYNC; */
> int flags = O_CREAT|O_TRUNC|O_WRONLY;
> mode_t mode = 0666;
>
> if (f_sync) {
> flags |= O_SYNC;
> }
>
> if ((thefd = open(filename, flags, mode)) == -1) {
> printf("open of \"%s\" failed for writing, errno=%d\n",
> filename, errno);
> exit(-1);
> }
>
> if (debug) printf("entering loop.\n");
>
> while(written < size) {
>
> this_blocksize = ((size - written) < blocksize) ?
> (size - written) : blocksize;
>
> markStart();
> if (debug) printf("writing [%d] bytes...\n", this_blocksize);
> ret = write(thefd, chunk, this_blocksize);
> markEnd();
> if (ret == -1) {
> printf("write failed.\n");
> exit(1);
> }
> written += this_blocksize;
> io_count++;
> }
>
> handleSignal(0);
> }
>
> int spew(char *tag)
> {
> struct timeval tv;
>
> gettimeofday(&tv, NULL);
> printf(" TS[%s]: %lu.%d\n", tag, tv.tv_sec, tv.tv_usec);
>
> return(0);
> }
>
> void initChunk(char ch) {
> memset(chunk, ch, MAX_BLOCKSIZE);
> }
>
> float diff(struct timeval *start, struct timeval *end)
> {
> float d = end->tv_sec - start->tv_sec +
> (end->tv_usec - start->tv_usec)/1000000.0;
>
> return(d);
> }
>
> bioctl -iv ami0:
> ----------------------------------------------------------------
> # bioctl -iv ami0
> Volume Status Size Device
> ami0 0 Online 218219151360 sd0 RAID5
> 0 Online 72834088960 0:0.0 noencl <COMPAQ BD07288277
> HPB2>
> '3KT06BVL000075237CP0'
> 1 Online 72834088960 0:1.0 noencl <COMPAQ BD07285A25
> HPB8>
> '3HZ6Z63500007433D7TT'
> 2 Online 72834088960 0:2.0 noencl <COMPAQ BD07287B4C
> HPB8>
> 'D20LF9XK'
> 3 Online 72834088960 0:3.0 noencl <COMPAQ BD07288277
> HPB2>
> '3KT06BXP00007523V3F7'
> ami0 1 Online 299976622080 sd1 RAID0
> 0 Online 299995496448 0:5.0 noencl <COMPAQ BD30089BBA
> HPB1>
> 'DA01P5B007CG0547'
> ami0 2 Hot spare 72834088960 0:4.0 noencl <COMPAQ BD0728A4B4
> HPBC>
> 'J20JWRZK'