From owner-freebsd-current Sun Jan 26 05:54:12 1997 Return-Path: Received: (from root@localhost) by freefall.freebsd.org (8.8.5/8.8.5) id FAA09505 for current-outgoing; Sun, 26 Jan 1997 05:54:12 -0800 (PST) Received: from godzilla.zeta.org.au (godzilla.zeta.org.au [203.2.228.19]) by freefall.freebsd.org (8.8.5/8.8.5) with ESMTP id FAA09498 for ; Sun, 26 Jan 1997 05:54:07 -0800 (PST) Received: (from bde@localhost) by godzilla.zeta.org.au (8.8.3/8.6.9) id AAA31786; Mon, 27 Jan 1997 00:50:34 +1100 Date: Mon, 27 Jan 1997 00:50:34 +1100 From: Bruce Evans Message-Id: <199701261350.AAA31786@godzilla.zeta.org.au> To: dg@root.com, swallace@ece.uci.edu Subject: Re: exec bug Cc: current@FreeBSD.ORG Sender: owner-current@FreeBSD.ORG X-Loop: FreeBSD.org Precedence: bulk > The only solution I can think of at the moment to this problem would be to >change the code to do a read of the file header into a malloced buffer. The >overhead for this would be very (unacceptably) high, however. Testing shows that the additional overhead would probably be small and negative, since it is small and negative outside the kernel. On a P133, the enclosed program prints the following times for various access sizes: mmap read malloc+read 4: 39 22 125 (usec) 32: 40 22 125 1024: 44 34 135 4096: 60 72 160 I guess mmap is slower to start up because pagefaults have more overhead than reads. What is the library malloc()+free() doing to be 5 times slower than read+lseek()? The kernel malloc() is fast enough to use :-). It takes a couple of usec for small allocations. The overheads when the header block isn't in memory are so much larger that the reading method probably doesn't matter unless it is completely unsuitable. It's not clear whether read-ahead would be good or bad. Bruce --- #include #include #include #include #include #include #include #define NITER 1000 #define PAGE_SIZE 4096 int main(int argc, char **argv) { size_t access_size; char buf[PAGE_SIZE]; int fd, i, j; char *malbuf; caddr_t p; struct timeval tv0, tv1; access_size = argc > 1 ? strtol(argv[1], NULL, 0) : 32; fd = open("/bin/cat", O_RDONLY); if (gettimeofday(&tv0, NULL) != 0) perror("gettimeofday 1"); for (i = 0; i < NITER; ++i) { p = mmap((caddr_t)0, PAGE_SIZE, PROT_READ, 0, fd, (off_t)0); if (p == MAP_FAILED) perror("mmap"); for (j = 0; j < access_size; j += sizeof(int)) *(volatile int *)(p + j); if (munmap(p, PAGE_SIZE) != 0) perror("munmap"); } if (gettimeofday(&tv1, NULL) != 0) perror("gettimeofday 2"); printf("mmap time = %.0f usec\n", (1e6 * (tv1.tv_sec - tv0.tv_sec) + (tv1.tv_usec - tv0.tv_usec)) / NITER); if (gettimeofday(&tv0, NULL) != 0) perror("gettimeofday 3"); for (i = 0; i < NITER; ++i) { if (read(fd, buf, access_size) != access_size) perror("read"); if (lseek(fd, (off_t)0, SEEK_SET) != 0) perror("lseek"); } if (gettimeofday(&tv1, NULL) != 0) perror("gettimeofday 4"); printf("read time = %.0f usec\n", (1e6 * (tv1.tv_sec - tv0.tv_sec) + (tv1.tv_usec - tv0.tv_usec)) / NITER); if (gettimeofday(&tv0, NULL) != 0) perror("gettimeofday 5"); for (i = 0; i < NITER; ++i) { /* malloc()/free() is much slower than read()! */ malbuf = malloc(PAGE_SIZE); if (malbuf == NULL) perror("malloc"); if (read(fd, malbuf, access_size) != access_size) perror("read"); if (lseek(fd, (off_t)0, SEEK_SET) != 0) perror("lseek"); free(malbuf); } if (gettimeofday(&tv1, NULL) != 0) perror("gettimeofday 6"); printf("malloc+read time = %.0f usec\n", (1e6 * (tv1.tv_sec - tv0.tv_sec) + (tv1.tv_usec - tv0.tv_usec)) / NITER); return 0; } ---