Skip to content

Commit

Permalink
Profiler: write to pprof directory (OpenDiablo2#405)
Browse files Browse the repository at this point in the history
* Profiler: fixed flags and output to pprof directory

* Profiler: dumpheap command writes to pprof/heap.pprof
  • Loading branch information
Intyre authored Jun 23, 2020
1 parent 336c671 commit 6ed86ee
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 38 deletions.
1 change: 1 addition & 0 deletions CONTRIBUTORS
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ wtfblub
q3cpma
averrin
Dylan "Gravestench" Knuth
Intyre

* DIABLO2 LOGO
Jose Pardilla (th3-prophetman)
Expand Down
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,18 +73,19 @@ the game in a different location, the base path may have to be adjusted.

## Profiling

There are many profiler options to debug performance issues. These can be enabled by suppling the following command-line option:
There are many profiler options to debug performance issues. These can be enabled by suppling the following command-line option and are saved in the `pprof` directory:

`go run . --profile=cpu,mem`
`go run . --profile=cpu`

Available profilers:\
`cpu` `mem` `block` `goroutine` `trace` `thread` `mutex`

You can export the profiler output with the following command:\
`go tool pprof --pdf ./OpenDiablo2 /var/path/to/profiler.pprof > file.pdf`
`go tool pprof --pdf ./OpenDiablo2 pprof/profiler.pprof > file.pdf`

You may need to install [Graphviz](http://www.graphviz.org/download/) in order to convert the profiler output.
Ingame you can create a heap dump by pressing `~` and typing `dumpheap`. A heap.pprof is written to the `pprof` directory.

You may need to install [Graphviz](http://www.graphviz.org/download/) in order to convert the profiler output.

## Roadmap

Expand Down
72 changes: 38 additions & 34 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"image/png"
"log"
"os"
"os/exec"
"runtime"
"runtime/pprof"
"strconv"
Expand Down Expand Up @@ -72,7 +71,7 @@ func main() {

region := kingpin.Arg("region", "Region type id").Int()
preset := kingpin.Arg("preset", "Level preset").Int()
profileOptions := kingpin.Flag("profile", "Profiles the program (cpu, mem, block, goroutine, trace, thread, mutex)").String()
profileOption := kingpin.Flag("profile", "Profiles the program, one of (cpu, mem, block, goroutine, trace, thread, mutex)").String()

kingpin.Parse()

Expand All @@ -83,35 +82,8 @@ func main() {
log.Fatal(err)
}

var profilers []func(*profile.Profile)
for _, profileOption := range strings.Split(*profileOptions, ",") {
switch strings.ToLower(strings.Trim(profileOption, " ")) {
case "cpu":
log.Printf("CPU profiling is enabled.")
profilers = append(profilers, profile.CPUProfile)
case "mem":
log.Printf("Memory profiling is enabled.")
profilers = append(profilers, profile.MemProfile)
case "block":
log.Printf("Block profiling is enabled.")
profilers = append(profilers, profile.BlockProfile)
case "goroutine":
log.Printf("Goroutine profiling is enabled.")
profilers = append(profilers, profile.GoroutineProfile)
case "trace":
log.Printf("Trace profiling is enabled.")
profilers = append(profilers, profile.TraceProfile)
case "thread":
log.Printf("Thread creation profiling is enabled.")
profilers = append(profilers, profile.ThreadcreationProfile)
case "mutex":
log.Printf("Mutex profiling is enabled.")
profilers = append(profilers, profile.MutexProfile)
}
}

if len(profilers) > 0 {
defer profile.Start(profilers...).Stop()
if len(*profileOption) > 0 {
enableProfiler(*profileOption)
}

if *region == 0 {
Expand Down Expand Up @@ -153,11 +125,11 @@ func initialize() error {
}

d2term.BindLogger()
d2term.BindAction("dumpheap", "dumps the heap to heap.out", func() {
fileOut, _ := os.Create("heap.out")
d2term.BindAction("dumpheap", "dumps the heap to pprof/heap.pprof", func() {
os.Mkdir("./pprof/", 0755)
fileOut, _ := os.Create("./pprof/heap.pprof")
pprof.WriteHeapProfile(fileOut)
fileOut.Close()
exec.Command("go", "tool", "pprof", "--pdf", "./OpenDiablo2", "./heap.out", ">", "./memprofile.pdf")
})
d2term.BindAction("fullscreen", "toggles fullscreen", func() {
fullscreen := !d2render.IsFullScreen()
Expand Down Expand Up @@ -482,3 +454,35 @@ func loadStrings() error {

return nil
}

func enableProfiler(profileOption string) {
var options []func(*profile.Profile)
switch strings.ToLower(strings.Trim(profileOption, " ")) {
case "cpu":
log.Printf("CPU profiling is enabled.")
options = append(options, profile.CPUProfile)
case "mem":
log.Printf("Memory profiling is enabled.")
options = append(options, profile.MemProfile)
case "block":
log.Printf("Block profiling is enabled.")
options = append(options, profile.BlockProfile)
case "goroutine":
log.Printf("Goroutine profiling is enabled.")
options = append(options, profile.GoroutineProfile)
case "trace":
log.Printf("Trace profiling is enabled.")
options = append(options, profile.TraceProfile)
case "thread":
log.Printf("Thread creation profiling is enabled.")
options = append(options, profile.ThreadcreationProfile)
case "mutex":
log.Printf("Mutex profiling is enabled.")
options = append(options, profile.MutexProfile)
}
options = append(options, profile.ProfilePath("./pprof/"))

if len(options) > 1 {
defer profile.Start(options...).Stop()
}
}

0 comments on commit 6ed86ee

Please sign in to comment.