Skip to content
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;
}