| Both sides previous revision Previous revision Next revision | Previous revision |
| dirhashdynamicmemory [2008/08/15 10:13] – NickBarkas | dirhashdynamicmemory [2009/07/07 10:17] (current) – NickBarkas |
|---|
| ===== Plan ===== | ===== Plan ===== |
| |
| * Either change dirhash memory allocation to use buffer cache, or keep existing memory allocation model but register new callback function to free older dirhashes when vm_lowmem events occur. | * Either change dirhash memory allocation to use buffer cache, or keep existing memory allocation model but register new callback function to free older dirhashes when vm_lowmem events occur. **Done** |
| * Once code works reasonably well in my own tests, call for testing from the community to shake out more bugs if possible. | * Once code works reasonably well in my own tests, call for testing from the community to shake out more bugs if possible. **Done** |
| * Test for performance differences with dynamic dirhash vs. static under different work loads (e.g. huge maildirs, subversion fsfs repositories with a great many revisions, different amounts of memory in machine, etc.) | * Test for performance differences with dynamic dirhash vs. static under different work loads (e.g. huge maildirs, subversion fsfs repositories with a great many revisions, different amounts of memory in machine, etc.). **Done** |
| * Get code in a state suitable for being committed to -CURRENT | * Get code in a state suitable for being committed to -CURRENT. **Done** |
| * (Time permitting) Begin work on on-disk directory indexing in UFS2. | * (Time permitting) Begin work on on-disk directory indexing in UFS2. **Not done** |
| |
| ===== Status ===== | ===== Status ===== |
| |
| I blog about this project [[http://moduli.net/soc/|here]]. The code I am working on can be found in the %%FreeBSD%% Perforce depot [[http://perforce.freebsd.org/depotTreeBrowser.cgi?FSPC=//depot/projects/soc2008/snb%2ddirhash&HIDEDEL=NO|here]]. | I blogged about this project [[http://moduli.net/soc/|here]]. The code I am working on can be found in the %%FreeBSD%% Perforce depot [[http://perforce.freebsd.org/depotTreeBrowser.cgi?FSPC=//depot/projects/soc2008/snb%2ddirhash&HIDEDEL=NO|here]]. |
| |
| (2008-6-19) I am working on implementing a function to be registered with EVENTHANDLER_REGISTER() for vm_lowmem events that will free dirhashes. I am trying to determine how to decide which hashes to free, and will need to find how many should be freed each time this event occurs. Determining the latter might be easiest through trial and error, watching how often vm_lowmem events pop up when the system is low on memory. | (2008-6-19) I am working on implementing a function to be registered with EVENTHANDLER_REGISTER() for vm_lowmem events that will free dirhashes. I am trying to determine how to decide which hashes to free, and will need to find how many should be freed each time this event occurs. Determining the latter might be easiest through trial and error, watching how often vm_lowmem events pop up when the system is low on memory. |
| |
| (2008-8-14) Updated patches again. Now there are two: one against HEAD {{dirhashdynamicmemory/dirhash_lowmem_head_2008-8-14.patch?linkonly|dirhash_lowmem_head_2008-8-14.patch}} and one that should work both on 7.0 and 7-STABLE {{dirhashdynamicmemory/dirhash_lowmem_7-stable_2008-8-14.patch?linkonly|dirhash_lowmem_7-stable_2008-8-14.patch}}. These fix a bug in the previous code where hashes older than 5 seconds would never be deleted and instead only one hash at the head of the TAILQ would be removed with each vm_lowmem event. Also, now the deletion code is more aggressive: all hashes older than 5 seconds (tunable via a sysctl, vfs.ufs.dirhash_reclaimage) will always be deleted when a vm_lowmem event occurs, and if that doesn't free up at least 10% of the memory currently being used by dirhash, more hashes will be destroyed from the head of the TAILQ until we do free up at least 10% of the memory initially used. Also, below I have posted some results from some benchmarking. | (2008-8-14) Updated patches again. Now there are two: one against HEAD {{dirhashdynamicmemory/dirhash_lowmem_head_2008-8-14.patch?linkonly|dirhash_lowmem_head_2008-8-14.patch}} and one that should work both on 7.0 and 7-STABLE {{dirhashdynamicmemory/dirhash_lowmem_7-stable_2008-8-14.patch?linkonly|dirhash_lowmem_7-stable_2008-8-14.patch}}. These fix a bug in the previous code where hashes older than 5 seconds would never be deleted and instead only one hash at the head of the TAILQ would be removed with each vm_lowmem event. Also, now the deletion code is more aggressive: all hashes older than 5 seconds (tunable via a sysctl, vfs.ufs.dirhash_reclaimage) will always be deleted when a vm_lowmem event occurs, and if that doesn't free up at least 10% of the memory currently being used by dirhash, more hashes will be destroyed from the head of the TAILQ until we do free up at least 10% of the memory initially used. Also, below I have posted some results from some benchmarking. |
| | |
| | (2008-10-8) Results about a whole bunch of new benchmarks are added below. Also, the dirhash code for 8-CURRENT has been updated in perforce to work with some new changes made to the dirhash code in SVN. New patch: {{dirhashdynamicmemory/dirhash_lowmem_head_2008-10-12.patch?linkonly|dirhash_lowmem_head_2008-10-12.patch}} |
| | |
| | (2008-11-19) My [[http://univ-rav.u-strasbg.fr/avc/courseaccess?id=2814&type=pdf|slides]] and [[http://univ-rav.u-strasbg.fr/avc/courseaccess?id=2814&type=ogg|audio]] from my talk at %%EuroBSDCon%% 2008 are available online. |
| | |
| | (2009-7-7) I committed the dirhash vm_lowmem handler to -CURRENT about a month ago, and it will be included in 8.0-RELEASE. Also I plan to commit a backport of these changes to 7-STABLE, probably around September. |
| |
| ===== Benchmarks ===== | ===== Benchmarks ===== |
| |
| Here is a comparison of the speed running a number of different tasks that are fairly filesystem intensive with and without my dirhash low memory event handling code compiled into the kernel. The system used for testing is a 1.83GHz Core Duo Macbook with 2GB of memory and a 5400RPM 2.5" SATA hard drive. It's running i386 8-CURRENT, and WITNESS and INVARIANTS related options in the kernel are disabled. The system was running multiuser with only a few extra processes like wpa_supplicant, sshd, and powerd running. The vfs.ufs.dirhash_maxmem sysctl was set to 100MB at all times for both kernels, and vfs.ufs.dirhash_reclaimage was 5 seconds when using the vm_lowmem handling kernel. Each test was run with a random amount of wait time from 1 to 5 minutes between each test, and the whole set of tests was repeated for a total of four runs for the set. | I measured the performance of the changes I made to the dirhash code using a Python script that does a number of different operations on large directories, hopefully in a fairly realistic way. The script can be found [[http://perforce.freebsd.org/fileLogView.cgi?FSPC=//depot/projects/soc2008/snb%2ddirhash/benchmark/dh%5fbench.py|here in perforce]]. It first untars 1000 randomly generated maildirs containing a total of one million tiny email messages. Then it begins ten threads which add new messages to these maildirs, while simultaneously kicking off a build of a %%FreeBSD%% kernel. The mail delivery threads continue running as the script then extracts a very large tarball containing the entire %%FreeBSD%% src subversion repository from a revision a few months old, checks out from the extracted repository and does a few other subversion operations on it, then removes the extracted repository. Next the script blocks until the mail delivery threads finish delivering all the messages specified in the script, and next kicks off ten threads that perform a number of IMAP operations on all of the maildirs. Once those are all finished, all the generated directories are removed. Times are measured for the initial maildir extraction, the kernel build, time to untar the svnroot, all svn operations, removing the svnroot while mail continue to be delivered, the mail creation threads, the imap threads, and removing all the remaining directories at the end. |
| | |
| | I ran the tests on both %%FreeBSD%% 7.0 and 8-CURRENT for the AMD64 architecture. A GENERIC kernel is used on 7.0, and on -CURRENT the only change to the GENERIC config is that INVARIANTS and WITNESS related options are disabled. Furthermore malloc debugging is disabled on the -CURRENT system in userland. On the 7.0 system the creation threads deliver a total of 25 000 new messages to maildirs, while on 8-CURRENT I increased this to 50 000 because delivering 25 000 messages would take less time than all the other tasks which run alongside the mail creation threads. |
| | |
| | The hardware used for all tests has a 1.8GHz Intel Core 2 Duo, 1GB memory, and a 3.5" 80GB 7200 RPM IDE hard drive. The maildirs are extracted, have messages added, and IMAP operations are done on a secondary hard drive, which is a 2.5" 40GB 5400RPM SATA drive. All tests are run with the system running multiuser, but not much besides sshd, openntpd, and postfix along with normal default %%FreeBSD%% daemons are running in the background. |
| | |
| | Each battery of tests is run 5 times for a number of different dirhash settings. Using a kernel without my patch, tests are run with the maximum dirhash memory usage at the default 2MB and 64MB. With the kernel containing the vm_lowmem handler patch, 64MB is used across the board but the dirhash_reclaimage parameter is tweaked. On 7.0, 1s, 3s, 5s, and 10s are all tried for reclaim age, and on 8-CURRENT all these values are tried in addition to 4s and 8s. I put the results from all the test runs into a Gnumeric spreadsheet here: {{dirhashdynamicmemory/dh_benchmark_results.gnumeric?linkonly|dh_benchmark_results.gnumeric}}. The graphs from this spreadsheet were exported as pngs and included below. |
| |
| | | mean run time - no vm_lowmem handler | std. deviation - no vm_lowmem handler | mean run time - with vm_lowmem handler | std. deviation - with vm_lowmem handler | | ==== FreeBSD 7.0 Results ==== |
| | postmark | 2378s | 16s | 2327s | 77s | | |
| | portsnap extract | 312s | 55s | 315s | 57s | | |
| | tar extract | 505s | 1,8s | 498s | 5,5s | | |
| | svn checkout | 1084s | 131s | 1023s | 16,7s | | |
| | rm -rf ports | 76s | 3,7s | 78s | 1,5s | | |
| | make buildworld | 4373s | 2,3s | 4382s | 23s | | |
| | rm -rf src | 115s | 6,5s | 115s | 9,1s | | |
| | rm -rf svnroot | 20s | 5,5s | 18,7s | 4,3s | | |
| |
| postmark was run with 1 000 000 files, 500 subdirectories, and 10 000 transactions. The portsnap extract test just involved extracting an already fetched ports tree into a clean directory with portsnap extract. tar extraction was of a bzipped tarball containing a copy of the %%FreeBSD%% svn repository, svnmirror-base-r179637.tbz2, fetched from ftp://ftp.freebd.org/pub/FreeBSD/development/subversion. The svn checkout test did a subversion checkout from this newly extracted local svnroot of revision 178000 from HEAD, and make buildworld was run in the checked out src directory. The different rm tests just timed doing rm -rf on the extracted ports and svnroot directories, and the checked out src directory. | {{dirhashdynamicmemory/maildirs7.png}} |
| | {{dirhashdynamicmemory/kernel7.png}} |
| | {{dirhashdynamicmemory/svnroot7.png}} |
| | {{dirhashdynamicmemory/svn7.png}} |
| | {{dirhashdynamicmemory/rmsvn7.png}} |
| | {{dirhashdynamicmemory/mail7.png}} |
| | {{dirhashdynamicmemory/imap7.png}} |
| | {{dirhashdynamicmemory/rmother7.png}} |
| |
| The difference in run times was not significantly different with the two versions of code. During the postmark and portsnap tests no vm_lowmem events were seen, but a few of them did get fired and delete dirhashes in the later tests that used more memory. This did not seem to slow things down much though. Another test run was bonnie++ -r 2048 -n 1000 -s 0 -u root, and that also had little difference in the number of various operations per second for the different kernels. | ==== FreeBSD 8-CURRENT Results ==== |
| |
| Next I will be testing different values for vfs.ufs.dirhash_reclaimage to find a more optimal value there. | {{dirhashdynamicmemory/maildirs8.png}} |
| | {{dirhashdynamicmemory/kernel8.png}} |
| | {{dirhashdynamicmemory/svnroot8.png}} |
| | {{dirhashdynamicmemory/svn8.png}} |
| | {{dirhashdynamicmemory/rmsvn8.png}} |
| | {{dirhashdynamicmemory/mail8.png}} |
| | {{dirhashdynamicmemory/imap8.png}} |
| | {{dirhashdynamicmemory/rmother8.png}} |
| |