Created
March 3, 2015 19:15
-
-
Save awreece/427ff5dc58b531615f4f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* This was a grand experiment - I would evaluate students based on the only | |
* meaningful metric, amount of memory they actually used. This would make slab | |
* allocators more interesting, as they could potentially be more efficient in | |
* larger programs. Unfortunately, it is *exceptionally* hard to measure the | |
* current memory usage of a program, and even harder to do so portably. | |
* | |
* The most promising approach was getrusage(2). This library call is available | |
* on Mac OSX and Linux, and offers the ability to get the maximum resident set | |
* size. At first blush this was promising, but unfortunately there were some | |
* complications. First the units for ru_maxrss are consistent accross | |
* platforms: on MacOSX the man page claims the unit is bytes, whereas on Linux | |
* the man page claims the unit is kilobytes. Even worse, getusage(2) does not | |
* interact in a clean way with mmap(2). For the following sequnce of operation, | |
* the program will likely print the same value of ru_maxrss both times: | |
* | |
* getrusage(RUSAGE_SELF, &usage); | |
* printf("%ld\n", usage.ru_maxrss); | |
* memset(mmap(NULL, 4096*10, PROT_WRITE|PROT_READ, | |
* MAP_ANONYMOUS|MAP_PRIVATE, 0, 0), 'A', 4096*10); | |
* getrusage(RUSAGE_SELF, &usage); | |
* printf("%ld\n", usage.ru_maxrss); | |
* | |
* Nearest I can tell, this is because ru_maxrss does not relate to the current | |
* resident set size. | |
* | |
* I then took a different tack: abandoning my dreams of a cross platform | |
* assignment, I chose to use /proc/self/statm from the proc(5) file-system. | |
* This was more promising, as it returned the actual resident set size. | |
* Unfortunately, this still did not interact cleanly with mmap. The following | |
* program will likely the same value from resident_bytes() every time: | |
* | |
* memlib_mmap(4096*1000); | |
* printf("%ld\n", resident_bytes()); | |
* memlib_mmap(4096*1000); | |
* printf("%ld\n", resident_bytes()); | |
* memset(memlib_mmap(4096*10), 'A', 4096*10) | |
* printf("%ld\n", resident_bytes()); | |
* | |
* Interestingly, if the last mmap size is 4096*1000, the resident memory as | |
* calculated by /proc/self/statm changes. It is unclear why this is or in | |
* what way the new value is related to the previous sequence of operations. | |
*/ | |
UNUSED static long | |
resident_bytes() | |
{ | |
int ret; | |
long size, resident, share, text, lib, data, dirty; | |
char buf[1024]; | |
(void) read_file("/proc/self/statm", buf, sizeof (buf)); | |
ret = sscanf(buf, "%ld %ld %ld %ld %ld %ld %ld", | |
&size, &resident, &share, &text, &lib, &data, &dirty); | |
VERIFY3S(ret, ==, 7); | |
return (resident * 4096); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment