There are a few options for post-processing, all within the set of supported Go APIs. One is to use the `-focus` flag of `go tool pprof` so it only displays samples that match a particular call stack. If the code to be profiled is in a single function, that might be all you need. Another is to set and clear "goroutine labels" / "tags" around the parts of the code that you want to inspect. That would mean changing the program to use https://pkg.go.dev/runtime/pprof#Do (or SetGoroutineLabels), and then asking "go tool pprof" to filter the samples. It looks like the `-tagfocus` flag should do that for you.
The 200ms pause when stopping a CPU profile is mostly a sleep; if I recall correctly, the runtime stops asking for SIGPROF deliveries immediately but then waits for any stragglers. And if you end up with several profile files, you can pass them all as arguments to `go tool pprof` and it will merge them for you. If you're looking for a continuous profiling option that works within Go (no sidecar), is centered around files (no collection infrastructure to manage), and gives you the full power of Go's native profiles, you might enjoy https://pkg.go.dev/github.com/rhysh/autoprof. Rhys On Wed, Nov 13, 2024 at 7:57 AM Ian Lance Taylor <i...@golang.org> wrote: > On Wed, Nov 13, 2024, 5:31 AM Jason E. Aten <j.e.a...@gmail.com> wrote: > >> All good. I still think that the hack of blocking and restoring the >> runtime's SIGPROF signal >> handler might actually work though. It might not work. But if it does, >> it is almost >> exactly what you were looking for. >> >> Ian or others more knowledgeable myself might be able to advise better if >> it _should_ >> work, but maybe give it a shot. You could ask on gopherslack too for >> ideas. >> > > > It does seem like blocking SIGPROF should work. Still takes a system > call, of course. > > That said for this kind of analysis I would probably try the Linux perf > tool. > > Ian > > > >> On Wed, Nov 13, 2024 at 12:55 PM Stephen Illingworth < >> stephen.illingwo...@gmail.com> wrote: >> >>> On Wednesday 13 November 2024 at 12:02:12 UTC Jason E. Aten wrote: >>> >>> > I've tried but this unfortunately, the Start and Stop processes are >>> too expensive and really require writing to a different file for every >>> stop. The nature of the program means I need to do the Start/Stop process >>> 60+ times per second, so it would generate a lot of files and be very slow >>> on top. >>> >>> Note that the StartCPUProfile call takes an io.Writer. Therefore a >>> simple *bytes.Buffer suffices. No files need be created. You can be much >>> faster than the file system. >>> >>> >>> Yes. I've tried that too. But it's the call to StopCPUProfile() which >>> takes a lot of time. Using a bytes.Buffer it takes over 200ms to complete. >>> It's not much quicker than using a os.File as the writer implementation. >>> >>> My deadline for everything is less than 16ms so the 'pausing' process >>> needs to take a lot less time than that. >>> >>> I could maybe live with the delay for benchmarking purposes but I'm also >>> left with the problem of "concatenated profiles". pprof doesn't support >>> that. If it did or if there was a way of post-processing the concatenated >>> profiles into one profile that might be a satisfactory outcome. >>> >>> >>> > func StartCPUProfile(w io.Writer) error >>> >>> Writing a benchmark for your subsystem is the hardest mentally, but most >>> likely the best choice for the long term. >>> >>> >>> You're absolutely right of course. But I was hoping for a mechanism that >>> could be activated when a user detects a problem with their own input data. >>> That might still be possible but I'll have to give it some thought. >>> >>> Thanks for the reply! >>> >>> -- >>> You received this message because you are subscribed to a topic in the >>> Google Groups "golang-nuts" group. >>> To unsubscribe from this topic, visit >>> https://groups.google.com/d/topic/golang-nuts/Emrx_W9eSig/unsubscribe. >>> To unsubscribe from this group and all its topics, send an email to >>> golang-nuts+unsubscr...@googlegroups.com. >>> To view this discussion visit >>> https://groups.google.com/d/msgid/golang-nuts/cd406d0c-c281-4e8f-99ac-6ffb5b3a16efn%40googlegroups.com >>> <https://groups.google.com/d/msgid/golang-nuts/cd406d0c-c281-4e8f-99ac-6ffb5b3a16efn%40googlegroups.com?utm_medium=email&utm_source=footer> >>> . >>> >> -- >> You received this message because you are subscribed to the Google Groups >> "golang-nuts" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to golang-nuts+unsubscr...@googlegroups.com. >> To view this discussion visit >> https://groups.google.com/d/msgid/golang-nuts/CAPNEFAYSGUGx2S6P9Mr4poOzBNSZ5u-4pBKcwMuHdCza76n8OQ%40mail.gmail.com >> <https://groups.google.com/d/msgid/golang-nuts/CAPNEFAYSGUGx2S6P9Mr4poOzBNSZ5u-4pBKcwMuHdCza76n8OQ%40mail.gmail.com?utm_medium=email&utm_source=footer> >> . >> > -- > You received this message because you are subscribed to the Google Groups > "golang-nuts" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to golang-nuts+unsubscr...@googlegroups.com. > To view this discussion visit > https://groups.google.com/d/msgid/golang-nuts/CAOyqgcXD2C4wfBYUyOZVTbdDG3TQzCguXCt5OAURfZ3N9Pan%2BA%40mail.gmail.com > <https://groups.google.com/d/msgid/golang-nuts/CAOyqgcXD2C4wfBYUyOZVTbdDG3TQzCguXCt5OAURfZ3N9Pan%2BA%40mail.gmail.com?utm_medium=email&utm_source=footer> > . > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion visit https://groups.google.com/d/msgid/golang-nuts/CA%2B_ENBDrNVkQ2AW_W57sMhzz4dGN45t%2B0Lg%2BLV%2BM-N9XnGCOxA%40mail.gmail.com.