20151014

실험 및 연구 진행
– PARSEC 워크로드를 Xen에서 overcommit해서 실행하면, 그 실행 시간의 오차가 심하다. 40~50% 정도. 아마 vcpu pinning이 되지 않아서일 것으로 예상한다.
– 하지만 그렇다고 해서 vcpu pinning을 해서 실험하는 것은 옳지 않다. 일반적인 상황에서 pinning하지 않고 실행할 뿐 아니라, pinning한다면 성능 저하가 심할 것이다. Work conserving이 잘 되지 않기 때문이다.
– Xen에서 vpmu를 활성화하고, perf를 사용해 DomU를 프로파일링하는 것에 성공함. xl console을 사용해 perf 값을 가져오려는 시도는 2015/08/14에 했으나, 잘 되지 않았음. 다시 프로그램을 짜보니 잘 되었다.

#!/usr/bin/python
import sys 
import subprocess
import shlex
import time

g_domain_id_console_map = {}
g_domain_id_perf_data_map = {}

#-------------------------------------------------------------------------------------
# connect_console 
#-------------------------------------------------------------------------------------
def connect_console(domain_id):
    global g_domain_id_console_map

    cmd = "xl console %s" % (domain_id)
    p = subprocess.Popen(cmd,
                         shell=True,
                         stdin=subprocess.PIPE,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE,
                         bufsize=0,
                         executable='/bin/bash')

    g_domain_id_console_map[domain_id] = p

#-------------------------------------------------------------------------------------
# is_console_logged_in 
#-------------------------------------------------------------------------------------
def is_console_logged_in(domain_id):
    global g_domain_id_console_map

    p = g_domain_id_console_map[domain_id]
    p.stdin.write("\n")
    p.stdin.flush()
    line = p.stdout.readline()
    while not "login" in line or not "~#" in line:
        p.stdin.write("\n")
        p.stdin.flush()
        if "login" in line:
            return False
        elif "~#" in line:
            return True
        line = p.stdout.readline()

#-------------------------------------------------------------------------------------
# console_login 
#-------------------------------------------------------------------------------------
def console_login(domain_id):
    global g_domain_id_console_map

    p = g_domain_id_console_map[domain_id]
    p.stdin.write("\n")
    p.stdin.write("root\n")
    p.stdin.flush()

#-------------------------------------------------------------------------------------
# perf_over_console 
#-------------------------------------------------------------------------------------
def perf_over_console(domain_id):
    global g_domain_id_console_map

    p = g_domain_id_console_map[domain_id]
    cmd = "perf stat "\
        + "-e cache-references "\
        + "-e cache-misses "\
        + "-e cycles "\
        + "-e instructions "\
        + "-- sleep 1\n"
    stdout = ""
    p.stdin.write(cmd)
    p.stdin.flush()

    line = p.stdout.readline()
    stdout += line
    while "elapsed" not in line :
        stdout += line
        line = p.stdout.readline()
    stdout += line
    splitted_stdout = stdout.split("\r\n")
    splitted_stdout = splitted_stdout[-9:-1]
    stdout = "\r\n".join(splitted_stdout) 
    return stdout

#-------------------------------------------------------------------------------------
# update_perf 
#-------------------------------------------------------------------------------------
def update_perf(domain_id, stdout):
    global g_domain_id_perf_data_map

    perf_data = {}
    splitted_data = stdout.split("\r\n")
    splitted_data = splitted_data[2:-2]
    for line in splitted_data:
        line = line.strip()
        splitted_line = line.split()
        value = int(splitted_line[0].replace(",", ""))
        category = splitted_line[1]
        perf_data[category] = value

    cycles = perf_data["cycles"]
    insns  = perf_data["instructions"]
    cache_refs = perf_data["cache-references"]
    cache_miss = perf_data["cache-misses"]

    ipc  = float(insns) / float(cycles)
    miss_rate = float(cache_miss) / float(cache_refs)
    mpki = float(cache_miss) / (float(insns) / 1000)
    mpkc = float(cache_miss) / (float(cycles) / 1000)

    perf_data["ipc"] = ipc
    perf_data["miss_rate"] = miss_rate
    perf_data["mpki"] = mpki
    perf_data["mpkc"] = mpkc

    g_domain_id_perf_data_map[domain_id] = perf_data

#-------------------------------------------------------------------------------------
# main 
#-------------------------------------------------------------------------------------
def main():
    global g_domain_id_perf_data_map

    domain_id = sys.argv[1]
    connect_console(domain_id)

    if not is_console_logged_in(domain_id):
        console_login(domain_id)
    else:
        pass

    stdout = perf_over_console(domain_id)
    update_perf(domain_id, stdout)
    for domain_id in g_domain_id_perf_data_map:
        print domain_id, g_domain_id_perf_data_map[domain_id]["ipc"]

if __name__ == "__main__":
    main()
Advertisements
Tagged with: , , , , , , , ,
Posted in 1) Memo

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

누적 방문자 수
  • 88,680 hits
%d bloggers like this: