First post on a new blog! Ring the bell.
But no time for chitchat now... :)
So, I was trying to write some computationally intensive code in Go (gc 1.0.2 Win64) in the past few days and a couple of things about performance didn't seem quite right (more on this later).
Hence I looked into profiling options and found references to pprof and a nice article by Russ Cox about it. I eagerly dove into it, only to be quickly disappointed by an output that looked like this:
(pprof) top10
Total: 2113 samples
298 14.1% 14.1% 298 14.1% 0000000000464d34
179 8.5% 22.6% 179 8.5% 0000000000418e83
157 7.4% 30.0% 157 7.4% 0000000000418e60
112 5.3% 35.3% 112 5.3% 0000000000403293
101 4.8% 40.1% 101 4.8% 0000000000464d4f
83 3.9% 44.0% 83 3.9% 000000000040329c
77 3.6% 47.7% 77 3.6% 0000000000418e7a
62 2.9% 50.6% 62 2.9% 0000000000456a38
37 1.8% 52.3% 37 1.8% 0000000000418e41
37 1.8% 54.1% 37 1.8% 0000000000435f57
No function names, only addresses. A quick Googling led to a couple of unsolved forum questions about the same problem, pointing at Windows as a common factor. Reluctant at the prospect of rebooting and moving my work over to Ubuntu I set out to see if pprof (a Perl script under Go\pkg\tool\[platform]) could be easily fixed.
Suprises suprise, it was.
Two issues were preventing the script from working under Windows:
But no time for chitchat now... :)
So, I was trying to write some computationally intensive code in Go (gc 1.0.2 Win64) in the past few days and a couple of things about performance didn't seem quite right (more on this later).
Hence I looked into profiling options and found references to pprof and a nice article by Russ Cox about it. I eagerly dove into it, only to be quickly disappointed by an output that looked like this:
(pprof) top10
Total: 2113 samples
298 14.1% 14.1% 298 14.1% 0000000000464d34
179 8.5% 22.6% 179 8.5% 0000000000418e83
157 7.4% 30.0% 157 7.4% 0000000000418e60
112 5.3% 35.3% 112 5.3% 0000000000403293
101 4.8% 40.1% 101 4.8% 0000000000464d4f
83 3.9% 44.0% 83 3.9% 000000000040329c
77 3.6% 47.7% 77 3.6% 0000000000418e7a
62 2.9% 50.6% 62 2.9% 0000000000456a38
37 1.8% 52.3% 37 1.8% 0000000000418e41
37 1.8% 54.1% 37 1.8% 0000000000435f57
No function names, only addresses. A quick Googling led to a couple of unsolved forum questions about the same problem, pointing at Windows as a common factor. Reluctant at the prospect of rebooting and moving my work over to Ubuntu I set out to see if pprof (a Perl script under Go\pkg\tool\[platform]) could be easily fixed.
Suprises suprise, it was.
Two issues were preventing the script from working under Windows:
- The use of /tmp for temp files. I used $ENV{'TEMP'} instead.
- Redirecting to /dev/null to test availability of external commands. Using the NUL file instead works under Win, in principle (if the command line options of those commands, such as nm, are the same). It turns out that's not quite enough, but adding one command ("$nm -n $image") to the list of candidates in the sub GetProcedureBoundaries does the trick.
Finally I was able to get some readable output:
(pprof) top
Total: 3361 samples
1043 31.0% 31.0% 1043 31.0% main.For5
333 9.9% 40.9% 333 9.9% CompareAndSwapUint32
303 9.0% 50.0% 303 9.0% runtime.procyield
252 7.5% 57.5% 252 7.5% runtime.casp
166 4.9% 62.4% 1068 31.8% sync.(*Mutex).Lock
124 3.7% 66.1% 124 3.7% runtime.atomicload
113 3.4% 69.4% 113 3.4% runtime.xadd
110 3.3% 72.7% 110 3.3% runtime.atomicloadp
104 3.1% 75.8% 104 3.1% math/rand.Int63
83 2.5% 78.3% 83 2.5% sync/atomic.AddUint32
Nice!
The fixes above are just enough to get the text output working. A couple more were needed for the web/graph visualisation.
A modified script can be found here.
A simple DIFF with the supplied version can reveal my changes.
If you're just getting started with Go, in order to get all this to work, you will need to:
Enjoy!
Nice!
The fixes above are just enough to get the text output working. A couple more were needed for the web/graph visualisation.
A modified script can be found here.
A simple DIFF with the supplied version can reveal my changes.
If you're just getting started with Go, in order to get all this to work, you will need to:
- Install Perl (e.g. ActivePerl).
- Add [YourPerl]\bin to your system or user PATH variable.
- Add Go\bin to your system or user PATH variable.
- Add Go\pkg\tool\[platform] to your system or user PATH variable.
- Under Windows, launch pprof with:
> perl [...]\Go\pkg\tool\[platform]\pprof_win.pl [executable] [profile] - Optional: if you want the web option to work, install graphviz and add its bin folder to your system or user PATH variable.
Ignore the error messages about files not found, and everything should work from the Windows command prompt. You may also be able to use the version of pprof supplied with go with shells like cygwin, MinGW, or Gow.
Enjoy!
5 comments:
Thanks for this - you saved me at least a day's worth of tinkering.
I still get some strange complaints about:
The system cannot find the path specified.
usage: addr2line binary
reads addresses from standard input and writes two lines for each:
function name
file:line
But things seem to work as advertised. Let's hope the Go dev team irons these wrinkles out.
Good point, I forgot to mention to ignore the error messages :)
I used the pprof_win.pl on
https://code.google.com/p/go/issues/detail?id=3879
and I still got the issue of "No function names, only addresses":
(pprof) top3
Total: 2 samples
1 50.0% 50.0% 1 50.0% 0000000000464987
1 50.0% 100.0% 1 50.0% 000000000048c0ec
0 0.0% 100.0% 2 100.0% 0000000000416e0f
Do you have an idea of where to investiguate next ?
Let's try this again...
On Windows 7, using go 1.1.2, pprof has been fixed.
In other words, the following command works:
go tool pprof path_to_executable path_to_profile_data
Make sure you use forward slashes in the path though.
Post a Comment