Created
April 17, 2018 08:08
-
-
Save Hermanio/75080f76de8a0815d9ba3fa7d2ed2bc8 to your computer and use it in GitHub Desktop.
testscript
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
import argparse | |
import csv | |
import logging | |
import math | |
import os | |
import subprocess | |
import sys | |
import time | |
import dbus | |
import psutil | |
class RaplPowerSource(): | |
intel_rapl_folder = '/sys/class/powercap/intel-rapl/' | |
MICRO_JOULE_IN_JOULE = 1000000.0 | |
def __init__(self, package_number=0): | |
self.package_number = package_number | |
self.intel_rapl_package_energy_file = os.path.join(self.intel_rapl_folder, 'intel-rapl:%d' % package_number, | |
'energy_uj') | |
self.intel_rapl_package_max_energy_file = os.path.join(self.intel_rapl_folder, 'intel-rapl:%d' % package_number, | |
'constraint_0_max_power_uw') | |
if (not os.path.exists(self.intel_rapl_package_energy_file) or not os.path.exists( | |
self.intel_rapl_package_max_energy_file)): | |
self.is_available = False | |
self.last_measurement_time = 0 | |
self.last_measurement_value = 0 | |
self.max_power = 0 | |
self.last_watts = 0 | |
return | |
self.is_available = True | |
self.last_measurement_time = time.time() | |
self.last_measurement_value = self.read_power_measurement_file() | |
# self.max_power = self.read_max_power_file() / self.MICRO_JOULE_IN_JOULE | |
self.max_power = 1 | |
self.last_watts = 0 | |
self.update() | |
def read_measurement(self, file_path): | |
try: | |
with open(file_path) as f: | |
value = f.read() | |
return float(value) | |
except: | |
return 0 | |
def read_max_power_file(self): | |
if not self.is_available: | |
return -1 | |
return float(self.read_measurement(self.intel_rapl_package_max_energy_file)) | |
def read_power_measurement_file(self): | |
if not self.is_available: | |
return -1 | |
return float(self.read_measurement(self.intel_rapl_package_energy_file)) | |
def get_power_usage(self): | |
if not self.is_available: | |
return -1 | |
current_measurement_value = self.read_power_measurement_file() | |
current_measurement_time = time.time() | |
joule_used = (current_measurement_value - self.last_measurement_value) / float(self.MICRO_JOULE_IN_JOULE) | |
logging.info("current " + str(current_measurement_value) + " last " + str(self.last_measurement_value)) | |
seconds_passed = current_measurement_time - self.last_measurement_time | |
watts_used = joule_used / seconds_passed | |
logging.info("Joule_Used " + str(joule_used) + " seconds_passed " + str(seconds_passed)) | |
self.last_measurement_value = current_measurement_value | |
self.last_measurement_time = current_measurement_time | |
self.last_watts = watts_used | |
try: | |
if watts_used > self.max_power: | |
self.max_power = math.ceil(watts_used) | |
logging.info("Max power updated " + str(self.max_power)) | |
except: | |
self.max_power = 1 | |
return watts_used | |
# Source super class implementation | |
def get_is_available(self): | |
return self.is_available | |
def update(self): | |
self.get_power_usage() | |
def get_reading(self): | |
return self.last_watts | |
def get_maximum(self): | |
return self.max_power | |
def reset(self): | |
self.max_power = 1 | |
self.last_watts = 0 | |
def get_summary(self): | |
return {'Cur Power': '%.1f %s' % (self.last_watts, self.get_measurement_unit()) | |
, 'Max Power': '%.1f %s' % (self.max_power, self.get_measurement_unit())} | |
def get_source_name(self): | |
return 'Power' | |
def get_measurement_unit(self): | |
return 'W' | |
def get_timestamp(): | |
return int(round(time.time() * 1000)) | |
def get_power_usage_in_watts(rapl): | |
return rapl.get_power_usage() | |
def get_cpu_freq(): | |
res = psutil.cpu_freq(True) | |
final = [] | |
for freq in res: | |
final.append(freq.current) | |
return pad_res(final) | |
def get_cpu_usage(): | |
return pad_res(psutil.cpu_percent(None, True)) | |
def pad_res(res, padcount=8): | |
while len(res) < padcount: | |
res.append(0) | |
return res | |
def measure(rapl): | |
res = [] | |
res.append(get_timestamp()) | |
res.append(get_power_usage_in_watts(rapl)) | |
res.extend(get_cpu_freq()) | |
res.extend(get_cpu_usage()) | |
return res | |
def repotest(run, test, cores): | |
log_file_name = "logs/test-{:s}-run{:d}-corecount-{:d}-{:d}.log".format(test, run, cores, int(time.time())) | |
rapl = RaplPowerSource() | |
poll_interval_in_seconds = 0.1 | |
start_time = time.time() | |
with open(log_file_name, 'a') as logfile: | |
logwriter = csv.writer(logfile, delimiter=',') | |
# start timer | |
start = time.time() | |
# start test | |
print("start test " + test + " with core count " + str(cores)) | |
p = subprocess.Popen(["yarn", "run", "build"], cwd="./testing/webrepotest") | |
# call turbo buust with args related to core count | |
subprocess.Popen(["python3", "turbo-buust", "enable", "--core-count", str(cores)], cwd="./implementation") | |
while p.poll() is None: | |
res = measure(rapl) | |
logwriter.writerow(res) | |
time.sleep(poll_interval_in_seconds - ((time.time() - start_time) % poll_interval_in_seconds)) | |
# stop timer | |
end = time.time() | |
print("test {:s} core count {:s} total runtime {:s}".format(test, str(cores), str(end - start))) | |
logfile.write("test {:s} core count {:s} total runtime {:s}".format(test, str(cores), str(end - start))) | |
# disable turbo buust | |
subprocess.Popen(["python3", "turbo-buust", "disable"], cwd="./implementation") | |
def repotestwithbg(run, test, cores, bgpct, stressngcores): | |
log_file_name = "logs/test-{:s}-run{:d}-corecount-{:d}-bgpct-{:d}-stressngcores-{:d}-{:d}.log".format(test, run, cores, bgpct, stressngcores, int(time.time())) | |
rapl = RaplPowerSource() | |
poll_interval_in_seconds = 0.1 | |
start_time = time.time() | |
with open(log_file_name, 'a') as logfile: | |
logwriter = csv.writer(logfile, delimiter=',') | |
# start timer | |
start = time.time() | |
# start test | |
print("start test " + test + " with core count " + str(cores)) | |
p = subprocess.Popen(["yarn", "run", "build"], cwd="./testing/webrepotest") | |
stressng = subprocess.Popen(["stress-ng", "-c", str(stressngcorecount), "-l", str(bgpct)]) | |
# call turbo buust with args related to core count | |
subprocess.Popen(["python3", "turbo-buust", "enable", "--core-count", str(cores)], cwd="./implementation") | |
while p.poll() is None: | |
res = measure(rapl) | |
logwriter.writerow(res) | |
time.sleep(poll_interval_in_seconds - ((time.time() - start_time) % poll_interval_in_seconds)) | |
# stop timer | |
end = time.time() | |
stressng.kill() | |
print("test {:s} core count {:s} total runtime {:s}".format(test, str(cores), str(end - start))) | |
logfile.write("test {:s} core count {:s} total runtime {:s}".format(test, str(cores), str(end - start))) | |
# disable turbo buust | |
subprocess.Popen(["python3", "turbo-buust", "disable"], cwd="./implementation") | |
def sysbench_nobg(run, test, cores, sysbench_cores): | |
log_file_name = "logs/test-{:s}-run{:d}-buustcorecount-{:d}-sysbenchcores-{:d}-{:d}.log".format(test, run, cores, | |
sysbench_cores, | |
int(time.time())) | |
print( | |
"sysbench test with turbobuust cores active {:d} and sysbench thread count {:d}".format(cores, sysbench_cores)) | |
rapl = RaplPowerSource() | |
poll_interval_in_seconds = 0.1 | |
start_time = time.time() | |
with open(log_file_name, 'a') as logfile: | |
logwriter = csv.writer(logfile, delimiter=',') | |
# start timer | |
start = time.time() | |
# start test | |
p = subprocess.Popen( | |
["sysbench", "cpu", "--threads={:d}".format(sysbench_cores), "--cpu-max-prime=20000", "run"], | |
stdout=subprocess.PIPE, stderr=subprocess.PIPE) | |
# call turbo buust with args related to core count | |
subprocess.Popen(["python3", "turbo-buust", "enable", "--core-count", str(cores)], cwd="./implementation") | |
while p.poll() is None: | |
res = measure(rapl) | |
logwriter.writerow(res) | |
time.sleep(poll_interval_in_seconds - ((time.time() - start_time) % poll_interval_in_seconds)) | |
# stop timer | |
end = time.time() | |
# write output and err to logs | |
(output, err) = p.communicate() | |
print(output.decode("utf-8")) | |
logfile.write(output.decode("utf-8")) | |
print(err.decode("utf-8")) | |
logfile.write(err.decode("utf-8")) | |
# disable turbo buust | |
subprocess.Popen(["python3", "turbo-buust", "disable"], cwd="./implementation") | |
def sysbench_withbg(run, test, cores, sysbench_cores, bgpct, stressngcorecount): | |
log_file_name = "logs/test-{:s}-run{:d}-buustcorecount-{:d}-sysbenchcores-{:d}-bgpct-{:d}-stressngcorecount-{:d}-{:d}.log".format( | |
test, run, cores, sysbench_cores, bgpct, stressngcorecount, int(time.time())) | |
print("test-{:s}-run{:d}-buustcorecount-{:d}-sysbenchcores-{:d}-bgpct-{:d}-stressngcorecount-{:d}".format(test, run, | |
cores, | |
sysbench_cores, | |
bgpct, | |
stressngcorecount)) | |
rapl = RaplPowerSource() | |
poll_interval_in_seconds = 0.1 | |
start_time = time.time() | |
with open(log_file_name, 'a') as logfile: | |
logwriter = csv.writer(logfile, delimiter=',') | |
# start timer | |
start = time.time() | |
# start test | |
p = subprocess.Popen( | |
["sysbench", "cpu", "--threads={:d}".format(sysbench_cores), "--cpu-max-prime=20000", "run"], | |
stdout=subprocess.PIPE, stderr=subprocess.PIPE) | |
stressng = subprocess.Popen(["stress-ng", "-c", str(stressngcorecount), "-l", str(bgpct)]) | |
# call turbo buust with args related to core count | |
subprocess.Popen(["python3", "turbo-buust", "enable", "--core-count", str(cores)], cwd="./implementation") | |
while p.poll() is None: | |
res = measure(rapl) | |
logwriter.writerow(res) | |
time.sleep(poll_interval_in_seconds - ((time.time() - start_time) % poll_interval_in_seconds)) | |
# stop timer | |
end = time.time() | |
# shut down background processes | |
stressng.kill() | |
# write output and err to logs | |
(output, err) = p.communicate() | |
print(output.decode("utf-8")) | |
logfile.write(output.decode("utf-8")) | |
print(err.decode("utf-8")) | |
logfile.write(err.decode("utf-8")) | |
# disable turbo buust | |
subprocess.Popen(["python3", "turbo-buust", "disable"], cwd="./implementation") | |
def cooldown(seconds=120): | |
print("Cooldown {:d}s...".format(seconds)) | |
time.sleep(seconds) | |
if __name__ == "__main__": | |
dbusprocess = subprocess.Popen(["sudo", "python3", "service.py"], cwd="./implementation") | |
print("waiting for service to come online...") | |
time.sleep(2) | |
print("attempt connection") | |
bus = dbus.SystemBus() | |
if not bus.name_has_owner("ee.ounapuu.TurboBuust"): | |
print("Service not running. Exit.") | |
sys.exit(1) | |
parser = argparse.ArgumentParser() | |
parser.add_argument("test", help="test name. Values: webrepotest, sysbenchnobg, sysbenchwithbg ") | |
args = parser.parse_args() | |
if args.test not in {"webrepotest", "sysbenchnobg", "sysbenchwithbg"}: | |
print("Invalid test {:s}".format(args.test)) | |
sys.exit(1) | |
if args.test == "webrepotest": | |
# Estimated runtime 20min | |
for run in range(1, 6): | |
for corecount in range(1, 5): | |
repotest(run, args.test, corecount) | |
cooldown(5) | |
if args.test == "webrepotestwithbg": | |
# Estimated runtime 20min | |
for run in range(1, 6): | |
for corecount in range(1, 5): | |
for bgpct in range(10, 35, 15): # bg stuff pct, max 20 is OK | |
for stressngcorecount in range(2, 5, 2): # stress core counts 1-3 is ok | |
repotestwithbg(run, args.test, corecount, bgpct,stressngcorecount) | |
cooldown(5) | |
if args.test == "sysbenchnobg": | |
# Estimated runtime 1h40min | |
# sysbench 1,2,3,4 core perf with xs in between | |
# turbobuust 1,2,3,4 core perf | |
for run in range(1, 6): | |
for sysbench_threads_active in range(1, 6, 2): | |
for turbobuust_cores_online in range(1, 5): | |
sysbench_nobg(run, args.test, turbobuust_cores_online, sysbench_threads_active) | |
cooldown(5) | |
if args.test == "sysbenchwithbg": | |
# Estimated runtime 1h30min | |
# sysbench 1,2,3,4 core perf with xs in between | |
# turbobuust 1234 | |
# bg pct 0-50 step 5 | |
for run in range(1, 4): # multiple tests for repeat results, deviation | |
for sysbench_threads_active in range(1, 3): # test with 1 or 2 threads, as more cannot be done yet | |
for turbobuust_cores_online in range(1, 6, 2): # cores online, goes thru all configs | |
for bgpct in range(10, 35, 15): # bg stuff pct, max 20 is OK | |
for stressngcorecount in range(4, 5): # stress core counts 1-3 is ok | |
sysbench_withbg(run, args.test, turbobuust_cores_online, sysbench_threads_active, bgpct, | |
stressngcorecount) | |
cooldown(5) | |
dbusprocess.kill() | |
sys.exit(0) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment