From cd61f905133544b62fc35fd49a7e5a9d19e103c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Geisend=C3=B6rfer?= Date: Sun, 10 Jan 2021 15:24:09 +0100 Subject: [PATCH] start cpu note --- cpu.md | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++ flame-abc.png | Bin 0 -> 36661 bytes flame-abc.txt | 3 ++ 3 files changed, 82 insertions(+) create mode 100644 cpu.md create mode 100644 flame-abc.png create mode 100644 flame-abc.txt diff --git a/cpu.md b/cpu.md new file mode 100644 index 0000000..4b0e51a --- /dev/null +++ b/cpu.md @@ -0,0 +1,79 @@ +🚧 This note is still work in progress, please come back later! 🚧 + +# Go's CPU profiler + +[TOC] + +## How it works + +Go's CPU profiler works by sampling the profiled program at a configurable rate of 100 Hz. A sample consists mostly of the stack trace of the goroutine that was interrupted. Below is an example of a program that has a function `A()` that sometimes calls function `C()` and `B()` which doesn't call anything. + +``` +------------------------------------> time +| | | | | | | | | | | | +A B A B A A A B A B A A + C C C + +<--> +10ms +``` + +The resulting [pprof output](./pprof.md) doesn't contain the raw sample events. Instead it aggregates all samples and reports the **samples/count** and **cpu/nanoseconds** values. The latter is [derrived](https://github.com/golang/go/blob/go1.15.6/src/runtime/pprof/proto.go#L354) by multiplying the sample count with the sample period and is therefore redundant. I suspect it's included because pprof doesnt support the count to time conversion, but if anybody has the full story please let me know! + +Back to the example above, the pprof output file would containing the following: + +| stack trace | samples/count | cpu/nanoseconds | +| ----------- | ------------- | --------------- | +| A | 5 | 50000000 | +| A C | 3 | 30000000 | +| B | 4 | 40000000 | + +Please note that the **stack trace** is a bit more complex in reality as it includes the exact program counter address at which your program was sampled as well as the line number in your code that it maps to. This information is usually omitted when visualizing the data as a [Flame Graph](http://www.brendangregg.com/flamegraphs.html), but can be very useful when drilling down into the details. Speaking of flame graphs, here is what the data above looks like when visualized: + +![Flame Graph for data above](./flame-abc.png) + +## Usage + +The various ways one can record CPU profiles in Go are listed below. + +1. The `go test` command has a `-cpuprofile` flag described that can be used to profile the benchmarks in your test suite like shown below. You can also [add a flag like this](https://golang.org/pkg/runtime/pprof/#hdr-Profiling_a_Go_program) to you own programs which might makes sense for command line tools. + + ``` + go test -cpuprofile benchmark.cpu.pb.gz -bench . + go tool pprof -http=:6061 benchmark.cpu.pb.gz + ``` + +2. The [net/http/pprof](net/http/pprof) allows you to setup http endpoints that can start/stop the CPU profiler via http requests on-demand and return the resulting pprof data file. You can directly pass a URL to such an endpoint to the pprof tool. + + ``` + go tool pprof -http=:6061 http://localhost:6060/debug/pprof/profile?seconds=30 + ``` + +3. You can programmatically start/stop the profiler via the [runtime/pprof API](https://golang.org/pkg/runtime/pprof/#StartCPUProfile). + + ```go + pprof.StartCPUProfile(outputFile) + defer pprof.StopCPUProfile() + // + ``` + +4. You can use a service such as [Datadog's Continious Profiler](https://www.datadoghq.com/product/code-profiling/) to automatically take and upload CPU profiles of your applications running in production. Disclaimer: I just started working for Datadog to take Go profiling to the next level. + +## Use Cases + +- Break down CPU utilization by functions or even line numbers. +- Break down CPU utilization by user-dimensions (endpoint, request_id, etc.) using [profiler labels](https://rakyll.org/profiler-labels/). + +## Anti-Use Cases + +- Understanding [Off-CPU](http://www.brendangregg.com/offcpuanalysis.html) time your program spends while waiting on I/O, Locks, Timers, Scheduling, etc. +- High-resolution sampling. The default rate is 100 Hz and you won't be able to go much higher for reasons outlined later on. + +## Todo + +- Talk about multi threading. +- setitimer +- Profiler labels +- bias +- performance overhead +- Discuss [Proposal: hardware performance counters for CPU profiling.](https://go.googlesource.com/proposal/+/refs/changes/08/219508/2/design/36821-perf-counter-pprof.md) \ No newline at end of file diff --git a/flame-abc.png b/flame-abc.png new file mode 100644 index 0000000000000000000000000000000000000000..9d1b6fe75bd0afa804302a81724708d24e6fc0d5 GIT binary patch literal 36661 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 literal 0 HcmV?d00001 diff --git a/flame-abc.txt b/flame-abc.txt new file mode 100644 index 0000000..13a0b23 --- /dev/null +++ b/flame-abc.txt @@ -0,0 +1,3 @@ +A 5 +A;C 3 +B 4