Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Phase Detection

This guide shows how to add phase markers to your programs for energy profiling.

Basic Concept

Print tokens to stdout and detect different sections of your code. The profiler detects these tokens and measures each section separately.

Add Phase Markers

Here are several examples in different languages:

Python:

print("__INIT__", flush=True)
load()

print("__PROCESSING__", flush=True)
process()

C:

printf("__INIT__\n");
fflush(stdout);
load();

printf("__PROCESSING__\n");
fflush(stdout);
process();

Rust:

#![allow(unused)]
fn main() {
println!("__INIT__");
std::io::stdout().flush().unwrap();
load();

println!("__PROCESSING__");
std::io::stdout().flush().unwrap();
process();
}

Important

Always flush stdout immediately after printing tokens, buffered output may not be detected in time.

Choose a Token Pattern

Create a regex pattern that matches your tokens:

# Simple pattern matching __WORD__
--token-pattern "__[A-Z_]+__"

# Custom pattern matching [WORD]
--token-pattern "\[A-Z_]+\]"

# Specific tokens only
--token-pattern "INIT|WORK|END"

Common patterns:

  • __[A-Z_]+__ - Matches __INIT__, __WORK__, __END__
  • <<<.*>>> - Matches <<<phase1>>>, <<<phase2>>>
  • \[PHASE-[0-9]+\] - Matches [PHASE-1], [PHASE-2]

Run the Profiler

sudo joule-profiler profile --token-pattern "__[A-Z_]+__" -- python my_script.py

Joule Profiler will profile the program by detecting tokens matching the configured pattern in the standard output. It will make a measurement between each token to report energy and various metrics across phases.

Complete Example

script.py:

import time

print("__LOAD__", flush=True)
data = [i for i in range(1000000)]
time.sleep(0.5)

print("__COMPUTE__", flush=True)
result = sum(data)
time.sleep(0.5)

print("__DONE__", flush=True)

Command:

sudo joule-profiler profile --token-pattern "__[A-Z_]+__" -- python script.py

Output:

Phase 0: __LOAD__ → __COMPUTE__
  Duration: 502 ms
  package-0: 1.2 J

Phase 1: __COMPUTE__ → __DONE__
  Duration: 501 ms
  package-0: 1.5 J

If you encounter some issues with phases, see troubleshooting.