go - 无法从 CPU 分析中获取数据
问题描述
我正在尝试学习使用 Go 的分析功能。考虑到这一点,我创建了这个简单的应用程序:https ://github.com/Matias-Barrios/countWords ,它只是计算给定txt文件的单词出现次数。
问题是,一旦创建了.cpu.prof文件,我什么都看不到。一旦我打开文件,我就会收到此错误:
(0) matias #> go tool pprof .cpu.prof
File: main
Type: cpu
Time: Oct 9, 2019 at 12:38am (-03)
Duration: 201.31ms, Total samples = 0
No samples were found with the default sample value type.
Try "sample_index" command to analyze different sample values.
Entering interactive mode (type "help" for commands, "o" for options)
(pprof) top
Showing nodes accounting for 0, 0% of 0 total
flat flat% sum% cum cum%
(pprof)
我在这里做错了什么?
注意:我的 Go 版本是go 版本 go1.13.1 linux/amd64
解决方案
对我来说,问题是我的代码执行得太快了。我所做的是使用runtime.SetCPUProfileRate更改采样率。请注意,在runtime.pprof.StartCPUProfile中,采样率为 100 Hz,建议为 500 Hz。
func StartCPUProfile(w io.Writer) error {
// The runtime routines allow a variable profiling rate,
// but in practice operating systems cannot trigger signals
// at more than about 500 Hz, and our processing of the
// signal is not cheap (mostly getting the stack trace).
// 100 Hz is a reasonable choice: it is frequent enough to
// produce useful data, rare enough not to bog down the
// system, and a nice round number to make it easy to
// convert sample counts to seconds. Instead of requiring
// each client to specify the frequency, we hard code it.
const hz = 100
cpu.Lock()
defer cpu.Unlock()
if cpu.done == nil {
cpu.done = make(chan bool)
}
// Double-check.
if cpu.profiling {
return fmt.Errorf("cpu profiling already in use")
}
cpu.profiling = true
runtime.SetCPUProfileRate(hz)
go profileWriter(w)
return nil
}
但在我的情况下,将其设置为 500 Hz 还不够快。查看runtime.SetCPUProfileRate的代码后,您似乎可以提供高达 100000 Hz 的频率。将其设置为足够大的值后,它解决了我的问题。
// SetCPUProfileRate sets the CPU profiling rate to hz samples per second.
// If hz <= 0, SetCPUProfileRate turns off profiling.
// If the profiler is on, the rate cannot be changed without first turning it off.
//
// Most clients should use the runtime/pprof package or
// the testing package's -test.cpuprofile flag instead of calling
// SetCPUProfileRate directly.
func SetCPUProfileRate(hz int) {
// Clamp hz to something reasonable.
if hz < 0 {
hz = 0
}
if hz > 1000000 {
hz = 1000000
}
lock(&cpuprof.lock)
if hz > 0 {
if cpuprof.on || cpuprof.log != nil {
print("runtime: cannot set cpu profile rate until previous profile has finished.\n")
unlock(&cpuprof.lock)
return
}
cpuprof.on = true
cpuprof.log = newProfBuf(1, 1<<17, 1<<14)
hdr := [1]uint64{uint64(hz)}
cpuprof.log.write(nil, nanotime(), hdr[:], nil)
setcpuprofilerate(int32(hz))
} else if cpuprof.on {
setcpuprofilerate(0)
cpuprof.on = false
cpuprof.addExtra()
cpuprof.log.close()
}
unlock(&cpuprof.lock)
}