📄 filesys.c
字号:
io_error("relative lseek(2)"); if (write(fd, (char *) buf, words) == -1) io_error("re write(2)"); } /* while we can read a block */ while (words == BUFSIZ); if (close(fd) == -1) io_error("close after rewrite"); get_delta_t((int) ReWrite); printf("done\n"); fflush(stdout); /* * Now rewrite the whole file from scratch, but a block at a time rather * than with stdio. Exercises space allocation a little more stringently, * and by comparison with the putc test, quantifies stdio overhead a bit. * Once again, dirty each block. */ newfile(name, &fd, &stream, 1); printf("Writing intelligently..."); for (words = 0; words < BUFSIZ / IntSize; words++) buf[words] = 0; fflush(stdout); timestamp(); for (words = bufindex = 0; words < (size / BUFSIZ); words++) { /* for each word */ if (bufindex == (BUFSIZ/IntSize)) bufindex = 0; buf[bufindex++]++; if (write(fd, (char *) buf, BUFSIZ) == -1) io_error("write(2)"); } /* for each word */ if (close(fd) == -1) io_error("close after fast write"); get_delta_t((int) FastWrite); printf("done\n"); fflush(stdout); /* * Now read them all back with getc, excercising default character- * at-a-time input. Do a character frequency count just to fool * any optimizers that may notice that they're not being used. */ newfile(name, &fd, &stream, 0); for (words = 0; words < 256; words++) chars[words] = 0; printf("Reading with getc()..."); fflush(stdout); timestamp(); for (words = 0; words < size; words++) { /* for each byte */ if ((next = getc(stream)) == EOF) io_error("getc(3)"); chars[next]++; } /* for each byte */ if (fclose(stream) == -1) io_error("fclose after getc"); get_delta_t((int) Getc); printf("done\n"); fflush(stdout); /* use the frequency count */ for (words = 0; words < 256; words++) sprintf((char *) buf, "%d", chars[words]); /* * Now suck it in, BUFSIZ at a time, as fast as we can. */ newfile(name, &fd, &stream, 0); if (lseek(fd, 0L, 0) == -1) io_error("lseek before read"); printf("Reading intelligently..."); fflush(stdout); timestamp(); do if ((words = read(fd, (char *) buf, BUFSIZ)) == -1) io_error("read(2)"); while (words); if (close(fd) == -1) io_error("close after read"); get_delta_t((int) FastRead); printf("done\n"); fflush(stdout); /* * Now do some random I/O. Originally these were binary searches, but * that is well-behaved, since the first few seeks are always the same. * Probably an application that was doing this kind of thing would keep * its own cache of the top few levels of the tree or whatever - we're * just interested in 'How much random I/O can be done?' */ newfile(name, &fd, &stream, 0); timestamp(); printf("Seeking..."); fflush(stdout); for (lseek_count = 0; lseek_count < Searches; lseek_count++) doseek(random() % size, fd, ((lseek_count % UpdateSeek) == 0)); if (close(fd) == -1) io_error("close after read"); get_delta_t((int) Binary); printf("done\n"); fflush(stdout); report(size); unlink(name);}static voidreport(size) int size;{ printf("\n"); printf("Times reported are elapsed / cpu / %%cpu usage.\n"); printf("\nSequential output\n"); printf("putc() bytes/sec: %d / %d / %.1f%%\n", (int) (((double) size) / delta[(int) Putc][Elapsed]), (int) (((double) size) / delta[(int) Putc][CPU]), delta[(int) Putc][CPU] / delta[(int) Putc][Elapsed] * 100.0); printf("write() bytes/sec: %d / %d / %.1f%%\n", (int) (((double) size) / delta[(int) FastWrite][Elapsed]), (int) (((double) size) / delta[(int) FastWrite][CPU]), delta[(int) FastWrite][CPU] / delta[(int) FastWrite][Elapsed] * 100.0); printf("putc() multiplier: %.1f / %.1f\n", delta[(int) Putc][Elapsed] / delta[(int) FastWrite][Elapsed], delta[(int) Putc][CPU] / delta[(int) FastWrite][CPU]); printf("Sequential output time: %.1f / %.1f / %.1f%%\n\n", delta[(int) FastWrite][Elapsed] + delta[(int) Putc][Elapsed], delta[(int) FastWrite][CPU] + delta[(int) Putc][CPU], (delta[(int) FastWrite][CPU] + delta[(int) Putc][CPU]) / (delta[(int) FastWrite][Elapsed] + delta[(int) Putc][Elapsed]) * 100.0); printf("\nSequential input\n"); printf("getc() bytes/sec: %d / %d / %.1f%%\n", (int) (((double) size) / delta[(int) Getc][Elapsed]), (int) (((double) size) / delta[(int) Getc][CPU]), delta[(int) Getc][CPU] / delta[(int) Getc][Elapsed] * 100.0); printf("read() bytes/sec: %d / %d / %.1f%%\n", (int) (((double) size) / delta[(int) FastRead][Elapsed]), (int) (((double) size) / delta[(int) FastRead][CPU]), delta[(int) FastRead][CPU] / delta[(int) FastRead][Elapsed] * 100.0); printf("getc() multiplier: %.1f / %.1f\n", delta[(int) Getc][Elapsed] / delta[(int) FastRead][Elapsed], delta[(int) Getc][CPU] / delta[(int) FastRead][CPU]); printf("Sequential input time: %.1f / %.1f / %.1f%%\n\n", delta[(int) Getc][Elapsed] + delta[(int) FastRead][Elapsed], delta[(int) Getc][CPU] + delta[(int) FastRead][CPU], (delta[(int) Getc][CPU] + delta[(int) FastRead][CPU]) / (delta[(int) Getc][Elapsed] + delta[(int) FastRead][Elapsed]) * 100.0); printf("\nSequential rewrite\n"); printf("Sequential rewrite bytes/sec: %d / %d / %.1f%%\n", (int) (((double) size) / delta[(int) ReWrite][Elapsed]), (int) (((double) size) / delta[(int) ReWrite][CPU]), delta[(int) ReWrite][CPU] / delta[(int) ReWrite][Elapsed] * 100.0); printf("Sequential rewrite time: %.1f / %.1f / %.1f%%\n", delta[(int) ReWrite][Elapsed], delta[(int) ReWrite][CPU], delta[(int) ReWrite][CPU] / delta[(int) ReWrite][Elapsed] * 100.0); printf("\nRandom I/O\n"); printf("Random reads/sec: %.1f / %.1f / %.1f%%\n", ((double) lseek_count) / delta[(int) Binary][Elapsed], ((double) lseek_count) / delta[(int) Binary][CPU], delta[(int) Binary][CPU] / delta[(int) Binary][Elapsed] * 100.0);}static voidnewfile(name, fd, stream, create) char * name; int * fd; FILE * * stream; int create;{ if (create) { /* create from scratch */ if (unlink(name) == -1 && *fd != -1) io_error("unlink"); *fd = open(name, O_RDWR | O_CREAT | O_EXCL, 0777); } /* create from scratch */ else *fd = open(name, O_RDWR, 0777); if (*fd == -1) io_error(name); *stream = fdopen(*fd, "r+"); if (*stream == NULL) io_error("fdopen");}static voidusage(){ fprintf(stderr, "usage: %s [-d scratch-directory] [-s size-in-megabytes]\n", myname); exit(1);}static voidtimestamp(){ last_timestamp = time_so_far(); last_cpustamp = cpu_so_far();}static void get_delta_t(which) int which;{ delta[which][Elapsed] = time_so_far() - last_timestamp; delta[which][CPU] = cpu_so_far() - last_cpustamp;}static double cpu_so_far(){#ifdef i386 struct tms tms; if (times(&tms) == -1) io_error("times"); return ((double) tms.tms_utime) / ((double) CLK_TCK) + ((double) tms.tms_stime) / ((double) CLK_TCK);#else struct rusage rusage; getrusage(RUSAGE_SELF, &rusage); return ((double) rusage.ru_utime.tv_sec) + (((double) rusage.ru_utime.tv_usec) / 1000000.0) + ((double) rusage.ru_stime.tv_sec) + (((double) rusage.ru_stime.tv_usec) / 1000000.0);#endif}static doubletime_so_far(){#ifdef i386 int val; struct tms tms; if ((val = times(&tms)) == -1) io_error("times"); return ((double) val) / ((double) CLK_TCK);#else struct timeval tp; if (gettimeofday(&tp, (struct timezone *) NULL) == -1) io_error("gettimeofday"); return ((double) (tp.tv_sec - basetime)) + (((double) tp.tv_usec) / 1000000.0);#endif}static voidio_error(message) char * message;{ char buf[BUFSIZ]; sprintf(buf, "%s: drastic I/O error (%s)", myname, message); perror(buf); exit(1);}/* * Do a typical-of-something random I/O. Any serious application that * has a random I/O bottleneck is going to be smart enough to operate * in a page mode, and not stupidly pull individual words out at * odd offsets. To keep the cache from getting too clever, some * pages must be updated. However an application that updated each of * many random pages that it looked at is hard to imagine. * However, it would be wrong to put the update percentage in as a * parameter - the effect is too nonlinear. Need a profile * of what Oracle or Ingres or some such actually does. * Be warned - there is a *sharp* elbow in this curve - on a 1-Mb file, * most substantial unix systems show >2000 random I/Os per second - * obviously they've cached the whole thing and are just doing buffer * copies. */static void doseek(where, fd, update) long where; int fd; int update;{ int buf[BUFSIZ / IntSize]; long probe; int size; probe = (where / BUFSIZ) * BUFSIZ; if (lseek(fd, probe, 0) != probe) io_error("lseek in doseek"); if ((size = read(fd, (char *) buf, BUFSIZ)) == -1) io_error("read in doseek"); /* every so often, update a block */ if (update) { /* update this block */ /* touch a word */ buf[((int) random() % (size/IntSize - 2)) + 1]--; if (lseek(fd, (long) probe, 0) != probe) io_error("lseek in doseek update"); if (write(fd, (char *) buf, size) == -1) io_error("write in doseek"); } /* update this block */} #ifdef i386static char randseed[] = "ioioio";static longrandom(){ return nrand48(randseed);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -