diff --git a/analyze/memcached_conn_scan.py b/analyze/memcached_conn_scan.py new file mode 100644 index 0000000000000000000000000000000000000000..b6cbc708a6af2eb038bd649fb7677ac410ecdd9b --- /dev/null +++ b/analyze/memcached_conn_scan.py @@ -0,0 +1,108 @@ +import os +import matplotlib.pyplot as plt + +experiments = [f for f in os.listdir('../data') + if f.startswith('memcached_conn_scan') and len(os.listdir(os.path.join('../data', f))) > 0] + +def parse_memcached_output(s): + lines = s.split('\n') + qps = int(float(lines[6].split(' ')[3])) + return qps + +def parse_perf_stat(s): + lines = s.split('\n') + llc_misses_u = int(list(filter(None, lines[5].split(' ')))[0].replace(',', '')) + llc_misses_k = int(list(filter(None, lines[5].split(' ')))[0].replace(',', '')) + return llc_misses_u + llc_misses_k + +def extract_conn_qps_exp(exp): + ret = ([10, 20, 40, 80, 160, 240, 320], [], []) + + for f in ret[0]: + with open(os.path.join('../data/', exp, 'c%d.txt' % (f,)), 'r') as fi: + qps = parse_memcached_output(fi.read()) + ret[1].append(qps) + + with open(os.path.join('../data/', exp, 'stat_c%d.txt' % (f,)), 'r') as fi: + misses = parse_perf_stat(fi.read()) + ret[2].append(misses) + + return ret + +def extract_conn_qps(threads, include_caladan = False): + ret = dict() + + for exp in experiments: + split = exp.split('.') + if split[-1] != ('t' + str(threads)): + continue + + if split[-2] == 'caladan' and not include_caladan: + continue + + name = split[-2] + if name[0].isdigit(): + name = 'default' + + ret[name] = extract_conn_qps_exp(exp) + + return ret + +def show_plot(threads, include_caladan = False): + plt.cla() + if include_caladan: + plt.title('Memcached connections vs QPS, %d threads, with Caladan' % (threads,)) + else: + plt.title('Memcached connections vs QPS, %d threads' % (threads,)) + + data = extract_conn_qps(threads, include_caladan) + + if include_caladan and threads == 1: + # Because we cannot run caladan on 1 threads, we use the t2 data + # but we half the QPS + name = 'caladan (per-thread)' + data[name] = extract_conn_qps_exp('memcached_conn_scan.5.4.0-136-generic.caladan.t2') + data[name] = (data[name][0], [qps / 2 for qps in data[name][1]], [misses / 2 for misses in data[name][2]]) + + for k in data: + plt.plot(data[k][0], data[k][1], label = k) + + plt.xlabel('Connections (per client w/ 7 * 8 clients)') + plt.ylabel('QPS') + + plt.legend() + if os.getenv('SAVE_FIGURE') != 'true': + plt.rcParams.update({'font.size': 16}) + plt.show() + else: + if include_caladan: + plt.savefig('../data/figs/memcached_conn_scan.t%d.caladan.png' % (threads,), dpi = 192) + else: + plt.savefig('../data/figs/memcached_conn_scan.t%d.png' % (threads,), dpi = 192) + + plt.cla() + if include_caladan: + plt.title('Memcached connections vs LLC misses, %d threads, with Caladan' % (threads,), y = 1.08) + else: + plt.title('Memcached connections vs LLC misses, %d threads' % (threads,), y = 1.08) + + for k in data: + plt.plot(data[k][0], data[k][2], label = k) + + plt.xlabel('Connections (per client w/ 7 * 8 clients)') + plt.ylabel('LLC misses') + + plt.legend() + if os.getenv('SAVE_FIGURE') != 'true': + plt.rcParams.update({'font.size': 16}) + plt.show() + else: + if include_caladan: + plt.savefig('../data/figs/memcached_conn_scan.llc_misses.t%d.caladan.png' % (threads,), dpi = 192) + else: + plt.savefig('../data/figs/memcached_conn_scan.llc_misses.t%d.png' % (threads,), dpi = 192) + +show_plot(1) +show_plot(1, True) +show_plot(8) +show_plot(8, True)