Profiler: write to pprof directory (#405)

* Profiler: fixed flags and output to pprof directory

* Profiler: dumpheap command writes to pprof/heap.pprof
This commit is contained in:
Intyre 2020-06-23 04:17:54 +02:00 committed by GitHub
parent 336c6719ee
commit 6ed86ee660
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 44 additions and 38 deletions

View File

@ -13,6 +13,7 @@ wtfblub
q3cpma
averrin
Dylan "Gravestench" Knuth
Intyre
* DIABLO2 LOGO
Jose Pardilla (th3-prophetman)

View File

@ -73,19 +73,20 @@ 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`
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
There is an in-progress [project roadmap](https://docs.google.com/document/d/156sWiuk-XBfomVxZ3MD-ijxnwM1X66KTHo2AcWIy8bE/edit?usp=sharing),

72
main.go
View File

@ -9,7 +9,6 @@ import (
"image/png"
"log"
"os"
"os/exec"
"runtime"
"runtime/pprof"
"strconv"
@ -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()
@ -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 {
@ -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()
@ -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()
}
}