Skip to content

Instantly share code, notes, and snippets.

@Hermanio
Created April 17, 2018 08:08
Show Gist options
  • Save Hermanio/75080f76de8a0815d9ba3fa7d2ed2bc8 to your computer and use it in GitHub Desktop.
Save Hermanio/75080f76de8a0815d9ba3fa7d2ed2bc8 to your computer and use it in GitHub Desktop.
testscript
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