Не могу заставить работать golang pprof

Я пытался профилировать некоторые приложения golang, но у меня это не получалось, я следовал этим двум руководствам:

Оба говорят, что после добавления нескольких строк кода в приложение вы должны выполнить свое приложение, я сделал это и получил следующее сообщение на экране:

2015/06/16 12:04:00 профиль: профилирование процессора включено, /var/folders/kg/4fxym1sn0bx02zl_2sdbmrhr9wjvqt/T/profile680799962/cpu.pprof

Итак, я понимаю, что выполняется профилирование, отправка информации в файл.

Но когда я вижу размер файла в любой тестируемой мной программе, он всегда равен 64 байтам.

Когда я пытаюсь открыть файл cpu.pprof с помощью pprof и выполняю команду «top10», я вижу, что в файле ничего нет:

("./fact" - мое приложение)

инструмент go pprof ./fact /var/folders/kg/4fxym1sn0bx02zl_2sdbmrhr9wjvqt/T/profile680799962/cpu.pprof

топ10 ->

(pprof) top10 0 из 0 всего (0%) фиксированная сумма% сумма% совокупная сумма%

Так что, когда я профилирую, похоже, что ничего не происходит.

Я тестировал его на Mac (этот пример) и в ubuntu с тремя разными программами.

Вы знаете, что я делаю не так?

Тогда пример программы очень прост, это код (очень простая факториальная программа, которую я беру из Интернета):

import "fmt"
import "github.com/davecheney/profile"

func fact(n int) int {
      if n == 0 {
        return 1
      }
      return n * fact(n-1)
}

func main() {
      defer profile.Start(profile.CPUProfile).Stop()
      fmt.Println(fact(30))
}

Спасибо, Фер


person Fersca    schedule 16.06.2015    source источник
comment
Во-первых, какую ОС вы используете? Во-вторых, pprof - это профилировщик выборки, и вы не делаете ничего, что можно было бы выполнить. Ваше приложение должно постоянно выполнять инструкции в течение некоторого значительного количества времени для накопления достаточного количества выборок (при использовании net / http / pprof время выборки по умолчанию составляет 30 секунд)   -  person JimB    schedule 16.06.2015
comment
Я работаю с OSX 10.10.2 (Йосемити). Сейчас я пытаюсь сделать так, чтобы профиль работал долгое время, и теперь вижу, что в файле больше информации :) спасибо!   -  person Fersca    schedule 16.06.2015
comment
вам также необходимо прочитать это: godoc.org/rsc.io/pprof_mac_fix   -  person JimB    schedule 16.06.2015


Ответы (2)


Как уже упоминалось, ваш код выполняется слишком быстро. Причина в том, что pprof работает, многократно останавливая вашу программу во время ее выполнения, смотря, какая функция выполняется в данный момент времени, и записывает это (вместе со всем стеком вызовов функции). Pprof сэмплов со скоростью 100 сэмплов в секунду. Это жестко запрограммировано в среде выполнения / pprof / pprof.go, как вы можете легко проверить (см. https://golang.org/src/runtime/pprof/pprof.go, строка 575 и комментарий над ней):

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

// Avoid queueing behind StopCPUProfile.
// Could use TryLock instead if we had it.
if cpu.profiling {
    return fmt.Errorf("cpu profiling already in use")
}

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

}

Чем дольше будет работать ваша программа, тем больше выборок можно будет сделать и тем более вероятно, что будут выполняться выборки коротких функций. Если ваша программа завершится до того, как будет сделан первый образец, то сгенерированный cpu.pprof будет пустым.

Как видно из приведенного выше кода, частота дискретизации устанавливается с помощью

runtime.SetCPUProfileRate(..)

Если вы вызываете runtime.SetCPUProfileRate () с другим значением перед вызовом StartCPUProfile (), вы можете переопределить частоту дискретизации. Во время выполнения программы вы получите предупреждающее сообщение, в котором говорится, что «время выполнения: нельзя установить скорость профиля процессора, пока не будет завершен предыдущий профиль». которые вы можете игнорировать. Это происходит потому, что pprof.go снова вызывает SetCPUProfileRate (). Поскольку вы уже установили значение, значение из pprof будет проигнорировано.

Кроме того, Дэйв Чейни выпустил новую версию своего инструмента профилирования, вы можете найти ее здесь: https://github.com/pkg/profile. Здесь вы можете, среди прочего, указать путь, по которому будет записан cpu.pprof:

defer profile.Start(profile.CPUProfile, profile.ProfilePath(".")).Stop()

Вы можете прочитать об этом здесь: http://dave.cheney.net/2014/10/22/simple-profiling-package-moved-updated

Кстати, ваша функция fact () быстро переполнится, даже если вы возьмете int64 в качестве параметра и возвращаемого значения. 30! составляет примерно 2 * 10 ^ 32, а int64 хранит значения только до 2 ^ 63-1, что примерно равно 9 * 10 ^ 18.

person alex    schedule 12.07.2015

Проблема в том, что ваша функция работает слишком быстро, и pprof не может ее выполнить. Попробуйте добавить цикл вокруг вызова fact и просуммировать результат, чтобы искусственно продлить программу.

person Stephan Dollberg    schedule 16.06.2015
comment
Спасибо, попробую и подскажу результат !! :) - person Fersca; 16.06.2015
comment
Теперь я вижу, после добавления for {;;} и сна, что в файле есть дополнительная информация. Спасибо :) - person Fersca; 16.06.2015