diff options
| author | Florian Fischer <florian.fl.fischer@fau.de> | 2018-07-17 00:15:25 +0200 |
|---|---|---|
| committer | Florian Fischer <florian.fl.fischer@fau.de> | 2018-07-17 00:15:25 +0200 |
| commit | 2026047c197bcf291733f8a4b3e5361f31e5cb77 (patch) | |
| tree | 81f04f857a4ead7480e5277be0119ca1be143956 | |
| parent | 9ef16832c7898b4d0af18fc12f1d11e24c4c925c (diff) | |
| download | allocbench-2026047c197bcf291733f8a4b3e5361f31e5cb77.tar.gz allocbench-2026047c197bcf291733f8a4b3e5361f31e5cb77.zip | |
use ps instead of memusage to get rss and vsz
| -rw-r--r-- | Makefile | 7 | ||||
| -rw-r--r-- | bench_conprod.py | 35 | ||||
| -rw-r--r-- | bench_loop.py | 35 | ||||
| -rw-r--r-- | bench_mysql.py | 18 | ||||
| -rw-r--r-- | memusage.c | 192 |
5 files changed, 48 insertions, 239 deletions
@@ -26,17 +26,12 @@ OBJECTS = $(notdir $(CC_SOURCES:.cc=.o)) $(notdir $(C_SOURCES:.c=.o)) OBJPRE = $(addprefix $(OBJDIR)/,$(OBJECTS)) MAKEFILE_LIST = Makefile -all: $(OBJDIR)/bench_loop $(OBJDIR)/memusage $(OBJDIR)/bench_conprod +all: $(OBJDIR)/bench_loop $(OBJDIR)/bench_conprod bench: all @if test \( ! \( -d bench.d \) \) ;then mkdir -p bench.d;fi bash -c "./bench.py" -$(OBJDIR)/memusage: $(OBJDIR)/memusage.o - @echo "ld $@" - @if test \( ! \( -d $(@D) \) \) ;then mkdir -p $(@D);fi - $(VERBOSE) $(CC) -o $@ $^ - $(OBJDIR)/bench_conprod: $(OBJDIR)/bench_conprod.o @echo "ld $@" @if test \( ! \( -d $(@D) \) \) ;then mkdir -p $(@D);fi diff --git a/bench_conprod.py b/bench_conprod.py index 44da48a..17c98eb 100644 --- a/bench_conprod.py +++ b/bench_conprod.py @@ -10,7 +10,7 @@ from common_targets import common_targets cmd = ("perf stat -x\; -e cpu-clock:k,cache-references,cache-misses,cycles," "instructions,branches,faults,migrations " - "build/memusage build/bench_conprod{0} {1} {1} {1} 1000000 {2}") + "build/bench_conprod{0} {1} {1} {1} 1000000 {2}") class Benchmark_ConProd(): def __init__(self): @@ -49,6 +49,7 @@ class Benchmark_ConProd(): # run cmd for each target for tname, t in self.targets.items(): + result = {"VSZ" : [] , "RSS" : []} env = {"LD_PRELOAD" : t[1]} if t[1] != "" else None @@ -56,33 +57,35 @@ class Benchmark_ConProd(): if verbose: print("\n" + tname, t, "\n", " ".join(target_cmd), "\n") - p = subprocess.run(target_cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE, + p = subprocess.Popen(target_cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE, env=env, universal_newlines=True) + + while p.poll() == None: + ps = subprocess.run(["ps", "-F", "--ppid", str(p.pid)], stdout=subprocess.PIPE) + lines = ps.stdout.splitlines() + if len(lines) == 1: # perf hasn't forked yet + continue + tokens = str(lines[1]).split() + result["VSZ"].append(tokens[4]) + result["RSS"].append(tokens[5]) + + p.wait() + + output = p.stderr.read() + if p.returncode != 0: print("\n" + " ".join(target_cmd), "exited with", p.returncode, ".\n Aborting Benchmark.") print(tname, t) print(p.stderr) - print(p.stdout) + print(output) return False if "ERROR: ld.so" in p.stderr: print("\nPreloading of", t[1], "failed for", tname, ".\n Aborting Benchmark.") return False - output = p.stderr.split("# End memusage\n") - if len(output) != 2: - print() - print(output) - print(tname, t) - print("Aborting output is not correct") - - result = {} - # Strip all whitespace from memusage output - result["memusage"] = [x.replace(" ", "").replace("\t", "") - for x in output[0].splitlines()] - # Handle perf output - csvreader = csv.reader(output[1].splitlines(), delimiter=';') + csvreader = csv.reader(output.splitlines(), delimiter=';') for row in csvreader: result[row[2].replace("\\", "")] = row[0].replace("\\", "") key = (tname, *args) diff --git a/bench_loop.py b/bench_loop.py index dcffa7f..c55f3ad 100644 --- a/bench_loop.py +++ b/bench_loop.py @@ -10,7 +10,7 @@ from common_targets import common_targets cmd = ("perf stat -x\; -e cpu-clock:k,cache-references,cache-misses,cycles," "instructions,branches,faults,migrations " - "build/memusage build/bench_loop{} 1.2 {} 1000000 {} 10") + "build/bench_loop{} 1.2 {} 1000000 {} 10") class Benchmark_Loop(): def __init__(self): @@ -49,6 +49,7 @@ class Benchmark_Loop(): # run cmd for each target for tname, t in self.targets.items(): + result = {"VSZ": [], "RSS" : []} env = {"LD_PRELOAD" : t[1]} if t[1] != "" else None @@ -56,12 +57,26 @@ class Benchmark_Loop(): if verbose: print("\n" + tname, t, "\n", " ".join(target_cmd), "\n") - p = subprocess.run(target_cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE, + p = subprocess.Popen(target_cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE, env=env, universal_newlines=True) + + while p.poll() == None: + ps = subprocess.run(["ps", "-F", "--ppid", str(p.pid)], stdout=subprocess.PIPE) + lines = ps.stdout.splitlines() + if len(lines) == 1: # perf hasn't forked yet + continue + tokens = str(lines[1]).split() + result["VSZ"].append(tokens[4]) + result["RSS"].append(tokens[5]) + + p.wait() + + output = p.stderr.read() + if p.returncode != 0: print("\n" + " ".join(target_cmd), "exited with", p.returncode, ".\n Aborting Benchmark.") print(tname, t) - print(p.stderr) + print(output) print(p.stdout) return False @@ -69,20 +84,8 @@ class Benchmark_Loop(): print("\nPreloading of", t[1], "failed for", tname, ".\n Aborting Benchmark.") return False - output = p.stderr.split("# End memusage\n") - if len(output) != 2: - print() - print(output) - print(tname, t) - print("Aborting output is not correct") - - result = {} - # Strip all whitespace from memusage output - result["memusage"] = [x.replace(" ", "").replace("\t", "") - for x in output[0].splitlines()] - # Handle perf output - csvreader = csv.reader(output[1].splitlines(), delimiter=';') + csvreader = csv.reader(output.splitlines(), delimiter=';') for row in csvreader: result[row[2].replace("\\", "")] = row[0].replace("\\", "") key = (tname, *args) diff --git a/bench_mysql.py b/bench_mysql.py index 59f5752..f3ce9cf 100644 --- a/bench_mysql.py +++ b/bench_mysql.py @@ -130,18 +130,18 @@ class Benchmark_MYSQL(): self.results[key].append(result) print() + + # Get memory stats from server + if "memusage" not in self.results: + self.results["memusage"] = {} + + ps = subprocess.run(["ps", "-F", str(self.server.pid)], stdout=subprocess.PIPE) + tokens = str(ps.stdout.splitlines()[1]).split() + self.results["memusage"][tname] = {"VSZ" : tokens[4], "RSS" : tokens[5]} + self.server.kill() self.server.wait() - # Strip all whitespace from memusage output - # result["memusage"] = [x.replace(" ", "").replace("\t", "") - # for x in output[0].splitlines()] - # - # # Handle perf output - # csvreader = csv.reader(output[1].splitlines(), delimiter=';') - # for row in csvreader: - # result[row[2].replace("\\", "")] = row[0].replace("\\", "") - if save: with open(self.name + ".save", "wb") as f: pickle.dump(self.results, f) diff --git a/memusage.c b/memusage.c deleted file mode 100644 index 1342ada..0000000 --- a/memusage.c +++ /dev/null @@ -1,192 +0,0 @@ -/* Utility to print running total of VmPeak and VmSize of a program */ -#define _GNU_SOURCE -#include <sys/types.h> -#include <sys/wait.h> -#include <signal.h> -#include <stdio.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> - -#define PATH_MAX 2048 - -int child_pid; - -static int main_loop(char *pidstatus) -{ - char *line; - char *vmsize; - char *vmpeak; - char *vmrss; - char *vmhwm; - - size_t len; - - FILE *f; - - vmsize = NULL; - vmpeak = NULL; - vmrss = NULL; - vmhwm = NULL; - line = malloc(128); - len = 128; - - f = fopen(pidstatus, "r"); - if (!f) return 1; - - /* Read memory size data from /proc/pid/status */ - while (!vmsize || !vmpeak || !vmrss || !vmhwm) - { - if (getline(&line, &len, f) == -1) - { - /* Some of the information isn't there, die. - Hopefully we have at least one measure. */ - return 1; - } - - /* Find VmPeak */ - if (!strncmp(line, "VmPeak:", 7)) - { - vmpeak = strdup(&line[7]); - } - - /* Find VmSize */ - else if (!strncmp(line, "VmSize:", 7)) - { - vmsize = strdup(&line[7]); - } - - /* Find VmRSS */ - else if (!strncmp(line, "VmRSS:", 6)) - { - vmrss = strdup(&line[7]); - } - - /* Find VmHWM */ - else if (!strncmp(line, "VmHWM:", 6)) - { - vmhwm = strdup(&line[7]); - } - } - free(line); - - fclose(f); - - /* Get rid of " kB\n"*/ - len = strlen(vmsize); - vmsize[len - 4] = 0; - len = strlen(vmpeak); - vmpeak[len - 4] = 0; - len = strlen(vmrss); - vmrss[len - 4] = 0; - len = strlen(vmhwm); - vmhwm[len - 4] = 0; - - /* Output results to stderr */ - fprintf(stderr, "%s;%s;%s;%s\n", vmsize, vmpeak, vmrss, vmhwm); - - free(vmpeak); - free(vmsize); - free(vmrss); - free(vmhwm); - - /* Success */ - return 0; -} - -static int usage(char *me) -{ - fprintf(stderr, "%s: filename args\n", me); - fprintf(stderr, "Run program, and print VmSize, VmPeak, VmRSS and VmHWM (in KiB) to stderr\n"); - - return 1; -} - -static int child(int argc, char **argv) -{ - char **newargs = malloc(sizeof(char *) * argc); - int i; - - /* We can't be certain that argv is NULL-terminated, so do that now */ - for (i = 0; i < argc - 1; i++) - { - newargs[i] = argv[i+1]; - } - newargs[argc - 1] = NULL; - - /* Launch the child */ - execvp(argv[1], newargs); - - return 0; -} - -static void sig_chld(int dummy) -{ - int status, child_val; - int pid; - - (void) dummy; - - pid = waitpid(-1, &status, WNOHANG); - if (pid < 0) - { - fprintf(stderr, "waitpid failed\n"); - return; - } - - /* Only worry about direct child */ - if (pid != child_pid) return; - - /* Get child status value */ - if (WIFEXITED(status)) - { - fprintf(stderr, "# End memusage\n"); - child_val = WEXITSTATUS(status); - exit(child_val); - } - else if (WIFSIGNALED(status)) - { - fprintf(stderr, "Child terminated by signal %d\n", WTERMSIG(status)); - exit(1); - } -} - -int main(int argc, char **argv) -{ - char buf[PATH_MAX]; - - struct sigaction act; - - if (argc < 2) return usage(argv[0]); - - act.sa_handler = sig_chld; - - /* We don't want to block any other signals */ - sigemptyset(&act.sa_mask); - - act.sa_flags = SA_NOCLDSTOP; - - if (sigaction(SIGCHLD, &act, NULL) < 0) - { - perror("sigaction"); - return 1; - } - - child_pid = fork(); - - if (!child_pid) return child(argc, argv); - - snprintf(buf, PATH_MAX, "/proc/%d/status", child_pid); - - fprintf(stderr, "VmSize;VmPeak;VmRSS;VmHWM\n"); - /* Continual scan of proc */ - while (!main_loop(buf)) - { - /* Wait for 0.1 sec */ - usleep(100000); - } - - /* This should never be reached we exit when our child exits */ - fprintf(stderr, "# End memusage\n"); - return 0; -} |
