Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

--track-energy feature #125

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
2 changes: 2 additions & 0 deletions pyperf/_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ def worker_cmd(self, calibrate_loops, calibrate_warmups, wpipe):
cmd.append('--tracemalloc')
if args.track_memory:
cmd.append('--track-memory')
if args.track_energy:
cmd.append('--track-energy')

if self.runner._add_cmdline_args:
self.runner._add_cmdline_args(cmd, args)
Expand Down
12 changes: 8 additions & 4 deletions pyperf/_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,6 @@ def __init__(self, values=None, warmups=None, processes=None,
# Set used to check that benchmark names are unique
self._bench_names = set()

# result of argparser.parse_args()
self.args = None

# callback used to prepare command line arguments to spawn a worker
# child process. The callback is called with prepare(runner.args, cmd).
# args must be modified in-place.
Expand Down Expand Up @@ -221,6 +218,9 @@ def __init__(self, values=None, warmups=None, processes=None,
help='option used with --compare-to to name '
'PYTHON as CHANGED_NAME '
'and REF_PYTHON as REF_NAME in results')
parser.add_argument("--track-energy",
action="store_true",
help="Measure energy instead of wall clock time.")

memory = parser.add_mutually_exclusive_group()
memory.add_argument('--tracemalloc', action="store_true",
Expand All @@ -230,6 +230,9 @@ def __init__(self, values=None, warmups=None, processes=None,

self.argparser = parser

# result of argparser.parse_args()
self.args = None

def _multiline_output(self):
return self.args.verbose or multiline_output(self.args)

Expand Down Expand Up @@ -420,7 +423,7 @@ def _main(self, task):
if task.name in self._bench_names:
raise ValueError("duplicated benchmark name: %r" % task.name)
self._bench_names.add(task.name)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary spaces in an empty line.

Suggested change

args = self.parse_args()
try:
if args.worker:
Expand Down Expand Up @@ -491,6 +494,7 @@ def task_func(task, loops):
dt = local_timer() - t0

return dt


task = WorkerProcessTask(self, name, task_func, metadata)
task.inner_loops = inner_loops
Expand Down
18 changes: 15 additions & 3 deletions pyperf/_worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
MAX_WARMUP_VALUES = 300
WARMUP_SAMPLE_SIZE = 20

# To invoke C in the context of --track-energy.
import ctypes
import os


class WorkerTask:
def __init__(self, runner, name, task_func, func_metadata):
Expand Down Expand Up @@ -63,9 +67,17 @@ def _compute_values(self, values, nvalue,
while True:
if index > nvalue:
break

raw_value = self.task_func(self, self.loops)
raw_value = float(raw_value)
if self.args.track_energy:
# Use environment variable for where the readings are stored.
c_lib = ctypes.CDLL(os.environ.get("READEN"))
# Energy value is the difference between recorded energies
# before and after executing task function.
e_0 = ctypes.c_ulonglong(c_lib.readen(os.environ.get("ENFILE").encode('utf-8')))
self.task_func(self, self.loops)
e_1 = ctypes.c_ulonglong(c_lib.readen(os.environ.get("ENFILE").encode('utf-8')))
raw_value = float(e_1.value) - float(e_0.value)
else:
raw_value = float(self.task_func(self, self.loops))
value = raw_value / (self.loops * inner_loops)

if not value and not calibrate_loops:
Expand Down
1 change: 1 addition & 0 deletions pyperf/energy.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
62
Binary file added pyperf/libreaden.so
Binary file not shown.
29 changes: 29 additions & 0 deletions pyperf/read_file.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

unsigned long long int readen(char *path) {
char *line = NULL;
size_t len = 0;
ssize_t read;
unsigned long long int data;

FILE *fd = fopen(path, "r");

if (fd == NULL)
exit(EXIT_FAILURE);

while ((read = getline(&line, &len, fd)) != -1) {
//Do nothing.
}

data = strtoull(line, NULL, 10);

if (line)
free(line);

fclose(fd);

return data;
}