NetBSD-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: vm.bufcache and git



Increasing kern.maxvnodes indeed helps; obviously that's about not
having to recycle vnodes per stat.  Since the basic issue is that stat
latency is greater for 180K files than a few, normal microbenchmarks
don't help.

I wrote a short program to run stat on many files, and to loop on
subsets.  It outputs data in xplot format, plotting stat latency in us
vs log2 of number of files.  To use it, create FILES containing one
filename per line (I used "find . -type f | egrep -v /.git", and yes I
know I should have quoted the . ...) and then

  statbench < FILES

On a system with big enough bufcache and maxvnodes, I found stat to take
about 4 us up to about 32 files, and then it starts to grow, reaching
9-10 us around 4096-8192 files, and then it remains relatively constant.

Attachment: stat.png
Description: PNG image

/* $Id: statbench.c,v 1.3 2010/05/26 17:18:00 gdt Exp $ */

#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/time.h>

#define MAXFILENAMES 200000

const char *filenames[MAXFILENAMES];
int nfilenames = 0;

do_run(int nstats)
{
  struct timeval before, after, delta;
  struct stat sb;
  int i, niters, n;
  double us_per_stat;

  assert (n <= nfilenames);

  gettimeofday(&before, NULL);
  niters = 1000000 / nstats;
  for (n = 0; n < niters; n++)
    for (i = 0; i < nstats; i++) {
      stat(filenames[i], &sb);
    }
  gettimeofday(&after, NULL);

  timersub(&after, &before, &delta);

  us_per_stat = delta.tv_sec * 1000000 + delta.tv_usec; /* Force to FP. */
  us_per_stat /= niters * nstats;

  printf("box %f %f\n", log2(nstats), us_per_stat);
  printf("; nstats %d  iterations %d total %d\n",
         nstats, niters, niters * nstats);
}

main()
{
  char input[1024];
  int nstats;

  /* Read all input, and just assert if too much or not enough. */
  while (fgets(input, sizeof(input), stdin) != NULL) {
    assert(nfilenames < MAXFILENAMES - 1);
    filenames[nfilenames++] = strdup(input);
  }
  assert(nfilenames >= 1);

  printf("double double\n");
  printf("title\nstat latency (us) vs log2 of number of files\n");
  printf("invisible 0 0\n");

  /*
   * nstats equal to nfilenames would be ok, but we use < to avoid
   * nfilenames twice in the case of nfilenames being exactly a power
   * of 2.
   */
  for (nstats = 1; nstats < nfilenames; nstats *= 2)
    do_run(nstats);
  do_run(nfilenames);
}

Attachment: pgp9N62q8awA2.pgp
Description: PGP signature



Home | Main Index | Thread Index | Old Index