From f7902eebeea5fd4fda91789087bd261ba8721a18 Mon Sep 17 00:00:00 2001 From: Armin Date: Thu, 11 Mar 2021 12:40:37 +0100 Subject: [PATCH] Fix broken references --- bench/README.md | 2 +- block.md | 4 ++-- cpu.md | 2 +- examples/block-net/README.md | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bench/README.md b/bench/README.md index 6559f70..4cc823c 100644 --- a/bench/README.md +++ b/bench/README.md @@ -16,7 +16,7 @@ go run . \ The benchmark works by spawning a new child process for the given number of `-runs` and every unique combination of parameters. The child reports the results to the parent process which then combines all the results in a CSV file. The hope is that using a new child process for every config/run eliminates scheduler, GC and other runtime state building up as a source of errors. -Workloads are defined in the [workloads.go](./workloads.go) file. For now the workloads are designed to be **pathological**, i.e. they try to show the worst performance impact the profiler might have on applications that are not doing anything useful other than stressing the profiler. The numbers are not intended to scare you away from profiling in production, but to guide you towards universally **safe profiling rates** as a starting point. +Workloads are defined in the [workloads_chan.go](./workload_chan.go) and [workloads_mutex.go](./workload_mutex.go) files. For now the workloads are designed to be **pathological**, i.e. they try to show the worst performance impact the profiler might have on applications that are not doing anything useful other than stressing the profiler. The numbers are not intended to scare you away from profiling in production, but to guide you towards universally **safe profiling rates** as a starting point. The CSV files are visualized using the [analysis.ipynb](./analysis.ipynb) notebook that's included in this directory. diff --git a/block.md b/block.md index 101e416..606b6f7 100644 --- a/block.md +++ b/block.md @@ -74,7 +74,7 @@ Block durations are aggregated over the lifetime of the program (while the profi pprof.Lookup("block").WriteTo(myFile, 0) ``` -Alternatively you can use [github.com/pkg/profile](https://pkg.go.dev/github.com/pkg/profile) for convenience, or [net/http/pprof](net/http/pprof) to expose profiling via http, or use a [continious profiler](https://www.datadoghq.com/product/code-profiling/) to collect the data automatically in production. +Alternatively you can use [github.com/pkg/profile](https://pkg.go.dev/github.com/pkg/profile) for convenience, or [net/http/pprof](https://golang.org/pkg/net/http/pprof/) to expose profiling via http, or use a [continious profiler](https://www.datadoghq.com/product/code-profiling/) to collect the data automatically in production. Last but not least you can use the [`runtime.BlockProfile`](https://golang.org/pkg/runtime/#BlockProfile) API to get the same information in a structured format. @@ -123,7 +123,7 @@ Anyway, what does all of this mean in terms of overhead for your application? It That being said, the benchmark results below (see [Methodology](./bench/)) should give you an idea of the **theoretical worst case** overhead block profiling could have. The graph `chan(cap=0)` shows that setting `blockprofilerate` from `1` to `1000` on a [workload](./bench/workload_chan.go) that consists entirely in sending tiny messages across unbuffered channels decreases throughput significantly. Using a buffered channel as in graph `chan(cap=128)` greatly reduces the problem to the point that it probably won't matter for real applications that don't spend all of their time on channel communication overheads. -It's also interesting to note that I was unable to see significant overheads for [`mutex`](.bench/workload_mutex.go) based workloads. I believe this is due to the fact that mutexes employe spin locks before parking a goroutine when there is contention. If somebody has a good idea for a workload that exhibits high non-spinning mutex contention in Go, please let me know! +It's also interesting to note that I was unable to see significant overheads for [`mutex`](./bench/workload_mutex.go) based workloads. I believe this is due to the fact that mutexes employe spin locks before parking a goroutine when there is contention. If somebody has a good idea for a workload that exhibits high non-spinning mutex contention in Go, please let me know! Anyway, please remember that the graphs below show workloads that were specifically designed to trigger the worst block profiling overhead you can imagine. Real applications will usually see no significant overhead, especially when using a `blockprofilerate` >= `10000` (10µs). diff --git a/cpu.md b/cpu.md index ff58cb2..1d778a9 100644 --- a/cpu.md +++ b/cpu.md @@ -41,7 +41,7 @@ The various ways one can record CPU profiles in Go are listed below. 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. +2. The [net/http/pprof](https://golang.org/pkg/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 diff --git a/examples/block-net/README.md b/examples/block-net/README.md index 329fb13..e8e98a2 100644 --- a/examples/block-net/README.md +++ b/examples/block-net/README.md @@ -1,6 +1,6 @@ # block-net -This [program](./main.go) explores the [question](https://twitter.com/rogpeppe/status/1359202847708037124) whether network i/o (e.g. waiting on socket read/write operations) will show up in the [block profiler](../block.md) or not. +This [program](./main.go) explores the [question](https://twitter.com/rogpeppe/status/1359202847708037124) whether network i/o (e.g. waiting on socket read/write operations) will show up in the [block profiler](/block.md) or not. The program does the following: @@ -22,5 +22,5 @@ However, as you can see below, the block profiler [captures](./block.pb.gz) only ![block-net](./block-net.png) -This means that [block profiler](../block.md) is generally not able to give a good idea about goroutines that are waiting on network i/o. +This means that [block profiler](/block.md) is generally not able to give a good idea about goroutines that are waiting on network i/o.