From owner-freebsd-performance@FreeBSD.ORG Wed Dec 27 07:10:49 2006 Return-Path: X-Original-To: freebsd-performance@freebsd.org Delivered-To: freebsd-performance@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 6940C16A412 for ; Wed, 27 Dec 2006 07:10:49 +0000 (UTC) (envelope-from markir@paradise.net.nz) Received: from smtp4.clear.net.nz (smtp4.clear.net.nz [203.97.37.64]) by mx1.freebsd.org (Postfix) with ESMTP id 2F47D13C46F for ; Wed, 27 Dec 2006 07:10:49 +0000 (UTC) (envelope-from markir@paradise.net.nz) Received: from [192.168.1.11] (121-72-68-249.dsl.telstraclear.net [121.72.68.249]) by smtp4.clear.net.nz (CLEAR Net Mail) with ESMTP id <0JAX003JI7XZQK30@smtp4.clear.net.nz> for freebsd-performance@freebsd.org; Wed, 27 Dec 2006 20:10:47 +1300 (NZDT) Date: Wed, 27 Dec 2006 20:10:46 +1300 From: Mark Kirkwood In-reply-to: <458B3651.8090601@paradise.net.nz> To: Mark Kirkwood Message-id: <45921C76.8020200@paradise.net.nz> MIME-version: 1.0 Content-type: text/plain; charset=ISO-8859-1; format=flowed Content-transfer-encoding: 7bit References: <458B3651.8090601@paradise.net.nz> User-Agent: Thunderbird 1.5.0.9 (X11/20061227) Cc: freebsd-performance@freebsd.org Subject: Re: Cached file read performance X-BeenThere: freebsd-performance@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Performance/tuning List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 27 Dec 2006 07:10:49 -0000 Mark Kirkwood wrote: > I used the attached program to read a cached > 781MB file sequentially and randomly with a specified block size (see > below). In the interest of making it easy for anyone to re-test this later, I'll in-line the program source here (I did post a link to my web space, but that could get cleaned up by accident...) ------------------------------------------------------------------------------------------- /* * readtest.c: read a file sequentially or randomly */ #include #include #include #include #include #include #include #include #include #include void usage(char *prog) { printf("usage %s filename blocksize 1|0 (0 - random, 1 - sequential)\n", prog); return; } int main(int argc, char **argv) { int fd; char *file; struct stat *fileinfo; char *buf; int blocksz; int numblocks, i; off_t offset, offsetmin, offsetmax; double offsetsum, offsetsumx2; int seq; int stats = 0; struct timeval starttp, endtp, elapsedtp; double elapsed; double iorate; if (argc != 4 && argc != 5) { usage(argv[0]); exit(1); } else { if ((file = (char *) malloc(strlen(argv[1]))) == NULL) { printf("out of memory!\n"); exit(2); } strcpy(file, argv[1]); blocksz = atoi(argv[2]); seq = atoi(argv[3]); if (argc == 5) stats = 1; } /* Start timing. */ gettimeofday(&starttp, NULL); if ((fd = open(file, O_RDONLY)) == -1) { /* Can't open the file. */ perror("cannot open"); exit(1); } else { /* How many random sequential access calls are needed? */ fileinfo = (struct stat*) malloc(sizeof(struct stat)); fstat(fd,fileinfo); numblocks = (fileinfo->st_size)/blocksz; free(fileinfo); } /* Allocate buffer. */ buf = (char *) malloc(blocksz); if (buf == NULL) { printf("out of memory!\n"); exit(2); } /* If we are random, initialize. */ if (seq != 1) srandom(2006122111); /* * Read the file sequentially or randomly. * If random then calculate the offset to seek to using the formula: * * offet in blocks = random() % (numblocks - 1) * */ for (i = 0; i < numblocks; i++) { if (seq == 1) { offset = (off_t)i * blocksz; /* only used for stats */ if (read(fd, buf, blocksz) != blocksz) { perror("read failed"); exit(1); } } else { offset = (off_t) (random() % (numblocks - 1)) * blocksz; if (lseek(fd, offset, SEEK_SET) == -1) { perror("seek failed"); exit(1); } if (read(fd, buf, blocksz) != blocksz) { perror("read failed"); exit(1); } } /* If we are collecting stats...*/ if (stats){ if (i == 0) { offsetmin = offsetmax = offset; offsetsum = (double)offset; offsetsumx2 = (double)offset*(double)offset; } else { if (offset < offsetmin) offsetmin = offset; if(offset > offsetmax) offsetmax = offset; offsetsum += (double)offset; offsetsumx2 += (double)offset*(double)offset; } } } free(buf); /* Close file now we are finished. */ close(fd); gettimeofday(&endtp, NULL); timersub(&endtp, &starttp, &elapsedtp); elapsed = (double)elapsedtp.tv_sec + (double)elapsedtp.tv_usec/1000000.0; iorate = (double)((double)numblocks*(double)blocksz)/(double)elapsed; printf("%s reads: %d of: %d bytes elapsed: %.4fs io rate: %.0f bytes/s\n", (seq == 1) ? "sequential" : "random", numblocks, blocksz,elapsed, iorate); if (stats) { printf("max offset: %d min offset: %d\n", offsetmax, offsetmin); printf("avg offset: %.0f ", offsetsum / (double)numblocks); printf("stddev offset: %.0f\n", sqrt(offsetsumx2 / (double)numblocks - (offsetsum / (double)numblocks) * (offsetsum / (double)numblocks))); } free(file); exit(0); }