Как профилировать из командной строки в Mac OS X?

Я пытаюсь профилировать код C/С++ в Mac OS X с помощью инструментов командной строки, я использую параметр -pg с gcc для запуска gprof в Linux, но я не могу найти gprof на Mac, хотя у меня есть описание на этой странице: Дополнительные средства командной строки (iOS) или Дополнительные средства командной строки (mac).

gprof:Produces execution profiles based on an execution analysis of a program.

Я установил инструменты командной строки, поэтому доступны другие инструменты командной строки, такие как otool и atos. Я googled, чтобы найти эту страницу (https://apple.stackexchange.com/info/154289/installing-gprof-on-mac), в которой говорится, что gprof не поддерживается, но я не уверен, когда у меня есть документ Apple, описывающий инструмент; во всяком случае, я пытался использовать brew для загрузки gprof, но это не сработало.

Я нашел Попытка использовать gprof с кодом С++ на Mac, но у меня нет вывода с instruments -t. Я также нашел Профилирование С++ на mac os x, но я не хочу открывать Инструменты, так как я хотел бы автоматизировать некоторые из процессов и попытаться сохранить кросс-платформу система.

  • Как использовать gprof для Mac OS X? Я использую OS X 10.10.
  • Как профилировать из командной строки с помощью или без gprof?

Ответы

Ответ 1

Странно слышать, что нет профилировщика gprof для OSX. OSX является сертифицированным unix, а профилировщик unix - gprof (на основе profil функции syscall/library, которая есть: https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man2/profil.2.html).

Есть проблемы с GNU gprof (часть binutils) в соответствии с https://apple.stackexchange.com/questions/154289/installing-gprof-on-mac (2014, благодаря удаленному пользователю Sreekanth Nagareddy), brew install -v binutils "*** Эта конфигурация не поддерживается в следующих подкаталогах:.. ld gas gprof"; OSX не указан в GNU gprof readme: http://code.metager.de/source/xref/gnu/src/gprof/README (2012) в разделе "Поддерживаемые платформы" (только OSF/1, SunOS, Solaris, HP-UX перечислен, я думаю, что он должен работать на Hurd и работать с Linuxes).

Но есть также реализация BSD gprof (проверьте https://en.wikipedia.org/wiki/gprof для истории и ссылок). Не пытались заставить его работать на OSX (нет OSX или укушенных яблок, более новых, чем рабочий стол 1995 года и ноутбук).

Существуют разные источники BSD gprof, например версия FreeBSD (https://github.com/freebsd/freebsd/tree/af3e10e5a78d3af8cef6088748978c6c612757f0/usr.bin/gprof) или древний оригинал 4.3BSD http://www.retro11.de/ouxr/43bsd/usr/src/ucb/gprof/. Оба варианта не поддерживают формат Mach-O, используемый в OSX.

Существует даже собственный gprof от Apple (основанный на BSD gprof от NetBSD/OpenBSD) в cctools Дарвина (Darwin является частью UNIX как ядра, так и пространства пользователя OSX, он/был/будет открытым исходным кодом): https://github.com/LeoTestard/Darwin/tree/master/cctools/gprof/https://github.com/darwin-on-arm/darwin-sdk/tree/master/cctools/gprof/http://src.gnu-darwin.org/src/usr.bin/gprof/gprof.c.html (некоторые более старые сочетания кода FreeBSD и сумасшедшие идеи свободы GNU).

Доступность gprof может зависеть от точной версии OSX или версии/пакетов Xcode; были gprof для 10.6.1, согласно http://louise.hu/poet/gprof-on-osx/ или в некоторой версии с 2012 года - https://rachelbythebay.com/w/2012/09/14/mac/ или даже в 2001 году: http://lists.apple.com/archives/darwin-development/2001/Apr/msg00617.html

Существует вариант использования instruments (часть Xcode Tools?) в командной строке, не знаю, как именно, но знайте, что инструменты - это современный и многофункциональный профилировщик.

Существует также iprofiler интерфейс командной строки для сбора профилей для Instruments.app, только что отмеченная man-страница из него https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man1/iprofiler.1.html (часть Xcode Tools версии 5.0, manpage из старой части сайта).

Существуют сторонние профилировщики, объявленные для поддержки OSX. Я знаю двух из них: valgrind и gperftools (google-perftools).

valgrind не является профилировщиком; это (медленная) платформа динамического инструментария с множеством инструментов, построенных поверх нее. Он включает в себя два инструмента, способных к профилированию: callgrind и cachegrind. Valgrind и оба инструмента не являются родным профилировщиком, они не профилируют приложение, поскольку оно будет работать на реальном процессоре в реальной жизни. Вместо этого valgrind выполняет программу на виртуальной машине и код машинного кода callgrind/cachegrind с счетчиками.

callgrind (http://valgrind.org/docs/manual/cl-manual.html) использует счетчик для каждого линейного блока инструкций для подсчета "сколько раз каждая инструкция будет выполнена" ( "Ir" , используемый для получения профилей - сортировка по процентам используемого времени); он также записывает вызовы/возвращает для сборки callgraph. Счетчик событий "Ir" правильный, чтобы получить счет выполнения команд (он также может эмулировать предсказание ветвления); но он не может быть использован для оценки реального времени работы. Реальный процессор (высокопроизводительный процессор, называемый суперскаляр, cpus вне порядка также сверхскалярный), способный выполнять более одной инструкции для каждого тактового цикла процессора; и он также часто неспособен выполнять какую-либо инструкцию, потому что может потребоваться запуск некоторых данных (данные из дальнего кеша или из памяти или из системного вызова или из другой команды с высокой задержкой, или неверно предсказанная ветка процессора приводит к тому, что адрес инструкции еще не читается/декодируется). Большинство прогрессивных процессоров могут даже не выполнять некоторые команды (некоторые могут выполнять до 8 "nop за каждый цикл, несколько мостов Intel Sandy/Ivy и новее не будут тратить время на" xor eax,eax "для записи нуля в регистр; они просто перенастраивают использование следующего регистра в обнуленный физический регистр). callgrind имеет типичное замедление 10-20 при профайлировании по сравнению с реальным запуском на аппаратном процессоре.

Cachegrind реализует те же инструменты, что и callgrind ( "Ir", ветки), но также может эмулировать иерархию кэша (кеш загружает/сохраняет/пропускает события). И это медленнее, чем callgrind.

Вывод из callgrind и cachegrind может быть просмотрен с помощью инструмента GUI kcachegrind (http://kcachegrind.sourceforge.net/, он может работать в ОС) или в командной строке, line tool callgrind_annotate.

Другим инструментом является gperftools (google-perftools, https://github.com/gperftools/gperftools), которые запускают программу на реальном процессоре. Чтобы использовать его, установите его с помощью homebrew, затем свяжите программу с libprofiler (добавьте -Lpath_to_installed_gperftools -lprofiler) и запустите с переменной среды CPUPROFILE, установленной для некоторого имени файла (CPUPROFILE=profile01 ./the_program). It will profile the program using interval timer ( setitimer ) and output profiling data to the filename, defined in CPUPROFILE env var. Then you can view profile data in command-line or with svg/web browser using pprof perl script from gperftools ( pprof./the_program profile01`).

Ответ 2

В моем собственном вопросе (CrazyPython) я смог использовать gperftools (pprof) с помощью @osgx. Здесь есть вопрос, и здесь является GitHub gist script. Для вашего удобства, вот script inline:

#!/usr/bin/env bash
# Licensed under the Unlicense. Full text at (http://unlicense.org/) - CrazyPython
g++ -std=c++11 $1 -o ./.executables/profiler/$(basename $1 .cpp) -g -O -lprofiler
echo "Finished compiling + linking"
CPUPROFILE=$1.out ./.executables/profiler/$(basename $1 .cpp)
./.executables/profiler/$(basename $1 .cpp)
pprof ./.executables/profiler/$(basename $1 .cpp) $1.out

Предупреждение: я попытался немного почистить его. Вероятно, это довольно много ненужных вариантов.