Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions tools/tracing/timeline/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,23 @@ Suite.
Run the following command with a **normal** user (*not* as `root` or using `sudo`):

```shell
./capture.py -e 50 -m /path/to/libmmtk_openjdk.so --no-root-nodes
./capture.py -e 47 -m /path/to/libmmtk_openjdk.so --no-root-nodes
```

`-e 50` means we only capture one GC in every 50 GCs because otherwise it will have to print too
`-e 47` means we only capture one GC in every 47 GCs because otherwise it will have to print too
much log. (Note: Printing in bpftrace is done via a fixed-size user/kernel space buffer, therefore
excessive printing will overrun the buffer and cause events to be dropped. The `-e` option helps
reducing the volume of log, thereby reducing the likelihood of buffer overrun and the time for
post-processing. If one single GC still produces too much log and overruns the buffer, the user
should consider setting the `BPFTRACE_PERF_RB_PAGES` environment variable. See the man page of
`bpftrace`.)
`bpftrace`.) We choose a large prime number, such as 47, because some GCs may exhibit periodic
behaviors under certain workloads. For example, generational GCs may alternate between nursery and
full-heap GC, making every odd GC a nursey GC, and every even GC a full-heap GC. If we capture
every 50th GC, we will only observe even or odd GCs because 50 is an even number, and it will give
us an illusion of "all GCs are nursery GC" or "all GCs are full-heap GC". This is an instance of
[aliasing effect].

[aliasing effect]: https://en.wikipedia.org/wiki/Aliasing

`--no-root-nodes` skips the `process_root_nodes` USDT which does not exist in `libmmtk_openjdk.so`.

Expand Down Expand Up @@ -86,7 +93,7 @@ This means things are working properly. Now re-run `./capture.py` again, but pi
file.

```
./capture.py -m /path/to/libmmtk_openjdk.so --no-root-nodes > mybenchmark.log
./capture.py -e 47 -m /path/to/libmmtk_openjdk.so --no-root-nodes > mybenchmark.log
```

Type the root password if prompted.
Expand Down
14 changes: 11 additions & 3 deletions tools/tracing/timeline/capture.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ def delete_lines_between(lines, begin, end):
raise Exception(f"Cannot find {begin} and {end} in the script. {begin_index} {end_index}")
del lines[begin_index:end_index + 1]

def eprint(*args, **kwargs):
print(*args, **kwargs, file=sys.stderr)

def main():
args = get_args()
here = Path(__file__).parent.resolve()
Expand Down Expand Up @@ -84,7 +87,7 @@ def main():
MMTK=mmtk_bin,
TMP_FILE=tmp.name)
if args.print_script:
print(content)
eprint(content)
tmp.write(content)
tmp.flush()

Expand All @@ -94,9 +97,14 @@ def main():

command_line = ["sudo", args.bpftrace] + extra_options + ["--unsafe", tmp.name]

if args.every % 2 == 0:
eprint(f"""\
WARNING! The value of the --every option is {args.every} which is an even number.
You may observe misleading results due to aliasing effect. See README.md""")

if args.dry_run:
print("Dry run. Command to execute:")
print(" ".join(f"'{c}'" for c in command_line))
eprint("Dry run. Command to execute:")
eprint(" ".join(f"'{c}'" for c in command_line))
# tempfile will be deleted at the end of `with`.
else:
# We use execvp to replace the current process instead of creating
Expand Down