Date: Sun, 29 Oct 2006 17:07:16 +0300 From: Yar Tikhiy <yar@comp.chem.msu.su> To: hackers@freebsd.org Subject: File trees: the deeper, the weirder Message-ID: <20061029140716.GA12058@comp.chem.msu.su>
next in thread | raw e-mail | index | archive | help
Folks, Here's a funny observation. A program essentially doing: for (;;) { mkdir("foo"); chdir("foo"); } starts as fast as the system permits, but settles to *exactly* one cycle per second at some depth that seems to depend only on the amount of RAM in the machine. An array sized at boot time seems to play a role there: for 128M the depth is ~7800, for 512M it's ~35000. The system feels very slow then, but only due to the fact that fs-related syscalls often take *exactly* one second to complete. As for the said program, it keeps its 1 Hz pace, mostly waiting on "vlruwk". It's killable, after a delay. The system doesn't show any signs of instability, and it's mostly idle according to top or systat! Weird, eh? Any ideas what's going on? -- Yar P.S. Here's the test program generalised and enhanced with timing diagnostics (-v). By setting several -v options, you'll get the diagnostics more often, exponentially. /* * Usage: * * xdir [-v -v ...] name-length tree-depth * * This program will create a chain of subdirectories rooted * in the current directory. Each subdir's name will be: * * 000 ... [ name-lenght times ] ... 000 * * The total depth will be tree-depth: * * 000+/000+/ ... [ tree-depth times] ... /000+/000+ */ #include <sys/types.h> #include <sys/stat.h> #include <sys/time.h> #include <err.h> #include <limits.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> int verbose; int main(int argc, char **argv) { int i, n, m, r; double dt; struct timeval tv0, tv; char buf[NAME_MAX + 1]; while ((i = getopt(argc, argv, "v")) != -1) switch (i) { case 'v': verbose++; break; default: errx(2, "bad option"); } argc -= optind; argv += optind; if (argv[0] == NULL || (n = atoi(argv[0])) <= 0) errx(2, "bad length"); if (argv[1] == NULL || (m = atoi(argv[1])) <= 0) errx(2, "bad depth"); if (n > NAME_MAX) errx(2, "too long"); sprintf(buf, "%0*d", n, 0); r = 1000; /* fool gcc */ if (verbose) { for (i = 1; i < verbose && r > 9; i++) r /= 10; gettimeofday(&tv0, NULL); } for (i = 1; i <= m; i++) { if (mkdir(buf, 0700) == -1) err(2, "mkdir %s", buf); if (chdir(buf) == -1) err(2, "chdir %s", buf); if (verbose && (i % r) == 0) { gettimeofday(&tv, NULL); dt = tv.tv_usec - tv0.tv_usec; dt /= 1000000; dt += tv.tv_sec - tv0.tv_sec; printf("%d (%.1lf)... ", i, r / dt); fflush(stdout); tv0 = tv; } } return (0); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20061029140716.GA12058>