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

Correct function index during translation #3232

Merged
merged 1 commit into from
Mar 18, 2024
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
23 changes: 14 additions & 9 deletions doc/perf_tune.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,17 +98,22 @@ You should only use this method for well tested wasm applications and make sure
Linux perf is a powerful tool to analyze the performance of a program, developer can use it to find the hot functions and optimize them. It is one profiler supported by WAMR. In order to use it, you need to add `--perf-profile` while running _iwasm_. By default, it is disabled.

> [!CAUTION]
> For now, only llvm-jit mode supports linux-perf.
> For now, only llvm-jit mode and aot mode supports linux-perf.

Here is a basic example, if there is a Wasm application _foo.wasm_, you'll execute.

```
$ perf record --output=perf.data.raw -- iwasm --perf-profile foo.wasm
$ perf record --output=perf.data.raw -- iwasm --enable-linux-perf foo.wasm
```

This will create a _perf.data_ and a _jit-xxx.dump_ under _~/.debug.jit/_ folder. This extra file is WAMR generated at runtime, and it contains the mapping between the JIT code and the original Wasm function names.
This will create a _perf.data_ and
- a _jit-xxx.dump_ under _~/.debug/jit/_ folder if running llvm-jit mode
- or _/tmp/perf-<pid>.map_ if running AOT mode

The next thing need to do is to merge _jit-xxx.dump_ file into the _perf.data_.

This file is WAMR generated. It contains information which includes jitted(precompiled) code addresses in memory, names of jitted (precompiled) functions which are named as *aot_func#N* and so on.

If running with llvm-jit mode, the next thing is to merge _jit-xxx.dump_ file into the _perf.data_.

```
$ perf inject --jit --input=perf.data.raw --output=perf.data
Expand Down Expand Up @@ -141,28 +146,28 @@ $ perf report --input=perf.data
[Flamegraph](https://www.brendangregg.com/flamegraphs.html) is a powerful tool to visualize stack traces of profiled software so that the most frequent code-paths can be identified quickly and accurately. In order to use it, you need to [capture graphs](https://github.com/brendangregg/FlameGraph#1-capture-stacks) when running `perf record`

```
$ perf record -k mono --call-graph=fp --output=perf.data.raw -- iwasm --perf-profile foo.wasm
$ perf record -k mono --call-graph=fp --output=perf.data.raw -- iwasm --enable-linux-perf foo.wasm
```

merge the _jit-xxx.dump_ file into the _perf.data.raw_.
If running with llvm-jit mode, merge the _jit-xxx.dump_ file into the _perf.data.raw_.

```
$ perf inject --jit --input=perf.data.raw --output=perf.data
```

generate the stack trace file.
Generate the stack trace file.

```
$ perf script > out.perf
```

[fold stacks](https://github.com/brendangregg/FlameGraph#2-fold-stacks).
[Fold stacks](https://github.com/brendangregg/FlameGraph#2-fold-stacks).

```
$ ./FlameGraph/stackcollapse-perf.pl out.perf > out.folded
```

[render a flamegraph](https://github.com/brendangregg/FlameGraph#3-flamegraphpl)
[Render a flamegraph](https://github.com/brendangregg/FlameGraph#3-flamegraphpl)

```
$ ./FlameGraph/flamegraph.pl out.folded > perf.foo.wasm.svg
Expand Down
13 changes: 8 additions & 5 deletions test-tools/trans-jitted-func-name/trans_wasm_func_name.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ def collect_import_section_content(wasm_objdump_bin: Path, wasm_file: Path) -> d
)

if p.stderr:
print("No content in import section")
return {}

import_section = {}
Expand All @@ -77,17 +78,19 @@ def collect_import_section_content(wasm_objdump_bin: Path, wasm_file: Path) -> d
if not line:
continue

if line.startswith(" - func"):
import_section.update("function", import_section.get("function", 0) + 1)
if re.search(r"^-\s+func", line):
import_section.update(function=import_section.get("function", 0) + 1)
else:
pass

assert len(import_section) > 0, "failed to retrive content of import section"
return import_section


def collect_name_section_content(wasm_objdump_bin: Path, wasm_file: Path) -> dict:
"""
execute "wasm_objdump_bin -j name -x wasm_file" and store the output in a list
execute "wasm_objdump_bin -j name -x wasm_file" and store the output in a dict
{1: xxxx, 2: yyyy, 3: zzzz}
"""
assert wasm_objdump_bin.exists()
assert wasm_file.exists()
Expand Down Expand Up @@ -117,7 +120,7 @@ def collect_name_section_content(wasm_objdump_bin: Path, wasm_file: Path) -> dic
assert m

func_index, func_name = m.groups()
name_section.update({func_index: func_name})
name_section.update({int(func_index): func_name})

assert name_section
return name_section
Expand Down Expand Up @@ -162,7 +165,7 @@ def replace_function_name(
new_line.append(sym)
continue

func_idx = m.groups()[-1]
func_idx = int(m.groups()[-1]) + import_function_count
if func_idx in name_section:
wasm_func_name = f"[Wasm] {name_section[func_idx]}"
else:
Expand Down