Cold-start-simulator
Contents
Linux / Cold start simulator
This is a very non-perfect simulation. Indeed - unfortunately - results vary by ~30%. However - it certainly slows down application startup under Linux - giving far more weight to cold-start issues, and a far better idea of the proportion of time spent in I/O.
Flushing Linux Caches
Recent versions of Linux (i.e. since 2.6.16) have added the ability to flush their caches. You can run:
sync ; echo 3 | sudo tee /proc/sys/vm/drop_caches
to write data to disk and then drop pagecache, dentry and inode caches. See [1] for more details.
I've not tested it with OpenOffice, but other when benchmarking other programs I get very low variance suggesting that it "does exactly what it says on the tin".
FreeBSD don't seem to provide a similar tool; with the people on IRC insisting that such a feature would never be useful. Ah well, maybe somebody will convince them.
Original tooling from Robert Love:
Using it
gcc fillmem.c -o fillmem gcc flushdisk.c -o flushdisk ./fillmem `free -m | grep ^Mem: | awk '{print $2}'` for i in `mount | grep ^/dev | awk '{print $1}'`; do ./flushdisk $i; done
Of course - this has the issue that while you evict pages they are potentially being required to re-render the terminal - make various things respond etc. Running the last 2 lines several times is perhaps better.
After running this it is probably wise to run & close a simple app - eg. 'gedit' that will touch all of the common libraries, X11, gtk+, fontconfig etc. and warm up the files commonly in the desktop working set.
fillmem
/* * fillmem.c - fill all memory to force the eviction of page cache * * Robert Love <rml@novell.com> */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #define MB (1024 * 1024) int main (int argc, char *argv[]) { unsigned long nr, i; if (argc < 2) { fprintf (stderr, "usage: %s <memory in MB>\n", argv[0]); return 1; } errno = 0; nr = strtoul (argv[1], NULL, 0); if (errno) { perror ("strtoul"); return 1; } for (i = 0; i < nr; i++) { unsigned long *data; data = malloc (MB); if (!data) { perror ("malloc"); return 1; } memset (data, i, MB); printf ("%p filled with %ld\n", data, i); } printf ("done\n"); return 0; }
flushdisk
/* * flushdisk.c - flush the buffer cache of a given blkdev * * Robert "Spunky" Love <rml@novell.com> */ #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <sys/ioctl.h> #include <sys/types.h> #include <sys/stat.h> #include <linux/fs.h> int main (int argc, char *argv[]) { char *blkdev; int fd, ret; if (argc < 2) { fprintf (stderr, "usage: %s <disk to flush>\n", argv[0]); return 1; } blkdev = argv[1]; fd = open (blkdev, O_RDONLY); if (fd < 0) { perror ("open"); return 1; } ret = ioctl (fd, BLKFLSBUF); if (ret) { perror ("ioctl"); return 1; } return 0; }