-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
tezc
committed
Jan 4, 2021
1 parent
499e3a0
commit efae56b
Showing
1 changed file
with
141 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
## Performance counters for Go | ||
|
||
Just a wrapper around [perf_event_open](https://man7.org/linux/man-pages/man2/perf_event_open.2.html). | ||
|
||
Useful when you want to get performance counters for some code snippet. | ||
Normally, you use 'perf' itself but it's not always possible to extract | ||
some piece of code from your project and isolate it for performance counters. | ||
|
||
## Notes | ||
- CPUs have limited PMU registers. So, performance counters can be activated at the | ||
same time are limited. (say 7 these days). | ||
- Some performance counters can be scheduled on specific PMU only. So, combination of | ||
some performance counters may not work or they will be multiplexed. | ||
- Check out "Measurement Time" section in the report to see if it's multiplexed. | ||
(less than %100) | ||
- Not all counters are supported by Linux or your CPU. | ||
- If you are surprised that some counters does not work, search scheduling | ||
algorithm of performance counters online. | ||
|
||
Usage : | ||
|
||
```go | ||
package main | ||
|
||
import ( | ||
"github.com/tezc/goperf" | ||
"hash/crc32" | ||
"os" | ||
) | ||
|
||
func main() { | ||
|
||
var x uint32 = 0 | ||
data := []byte("hello world!") | ||
|
||
goperf.Start() | ||
|
||
// long running code | ||
for i := 0; i < 10000000; i++ { | ||
x += crc32.ChecksumIEEE(data) | ||
} | ||
|
||
goperf.End() | ||
|
||
os.Exit(int(x)) | ||
} | ||
|
||
``` | ||
|
||
Output : | ||
|
||
``` | ||
| Event | Value | Measurement time | ||
--------------------------------------------------------------- | ||
| time (seconds) | 0.22 | (100,00%) | ||
| cpu-clock | 219,754,463.00 | (100.00%) | ||
| task-clock | 219,754,469.00 | (100.00%) | ||
| page-faults | 4.00 | (100.00%) | ||
| context-switches | 0.00 | (100.00%) | ||
| cpu-migrations | 0.00 | (100.00%) | ||
| page-fault-minor | 4.00 | (100.00%) | ||
| cpu-cycles | 911,266,695.00 | (100.00%) | ||
| instructions | 2,300,365,430.00 | (100.00%) | ||
| cache-misses | 14,812.00 | (100.00%) | ||
| L1D-read-miss | 11,385.00 | (100.00%) | ||
| L1I-read-miss | 48,424.00 | (100.00%) | ||
``` | ||
|
||
|
||
You can add or disable counters, check Counters table for the full list : | ||
|
||
|
||
```go | ||
package main | ||
|
||
import ( | ||
"github.com/tezc/goperf" | ||
"hash/crc32" | ||
"os" | ||
) | ||
|
||
func main() { | ||
|
||
var x uint32 = 0 | ||
data := []byte("hello world!") | ||
|
||
goperf.Disable("page-faults") | ||
goperf.Disable("context-switches") | ||
goperf.Enable("L1D-read-miss") | ||
goperf.Start() | ||
|
||
// long running code | ||
for i := 0; i < 10000000; i++ { | ||
x += crc32.ChecksumIEEE(data) | ||
} | ||
|
||
goperf.End() | ||
|
||
os.Exit(int(x)) | ||
} | ||
``` | ||
|
||
Run multiple time : | ||
|
||
```go | ||
package main | ||
|
||
import ( | ||
"github.com/tezc/goperf" | ||
"hash/crc32" | ||
"os" | ||
) | ||
|
||
func main() { | ||
|
||
var x uint32 = 0 | ||
data := []byte("hello world!") | ||
|
||
goperf.Start() | ||
// long running code | ||
for i := 0; i < 10000000; i++ { | ||
x += crc32.ChecksumIEEE(data) | ||
} | ||
goperf.End() | ||
|
||
|
||
|
||
test := []byte("test!") | ||
|
||
goperf.Start() | ||
// long running code | ||
for i := 0; i < 10000000; i++ { | ||
x += crc32.ChecksumIEEE(test) | ||
} | ||
goperf.End() | ||
|
||
|
||
os.Exit(int(x)) | ||
} | ||
``` |