我正在尝试使用命令行工具在Mac OS X上分析C / C ++代码,我使用-pg
选项和gcc
在Linux上运行gprof
,但我可以'似乎在Mac上找到了gprof
,即使我在此页面中有说明:Additional Command-Line Tools (iOS)或Additional Command-Line Tools (mac)。
gprof:Produces execution profiles based on an execution analysis of a program.
我安装了命令行工具,因此可以使用其他命令行工具,例如otool
和atos
。我搜索了这个页面(https://apple.stackexchange.com/questions/154289/installing-gprof-on-mac),表示不支持gprof
,但我不确定何时有Apple文档描述该工具;无论如何,我尝试使用brew
下载gprof
,但它没有用。
我找到Attempting to use gprof with C++ code on a Mac,但我没有instruments -t
的输出。我还发现Profiling c++ on mac os x,但我不想打开Instruments,因为我想自动化一些进程并尝试保持跨平台系统。
gprof
?答案 0 :(得分:7)
听说OSX没有gprof
个探测器很奇怪。 OSX是经过认证的unix,unix的分析器是gprof
(基于profil
系统调用/库函数,它位于https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man2/profil.2.html)。
根据https://apple.stackexchange.com/questions/154289/installing-gprof-on-mac(2014年;感谢Sreekanth Nagareddy用户删除的答案),GNU gprof(binutils的一部分)存在问题,brew install -v binutils
" ***此配置不是支持在以下子目录中:.. ld gas gprof&#34 ;; OSX未在GNU gprof自述文件中列出:http://code.metager.de/source/xref/gnu/src/gprof/README(2012)in"支持的平台" (仅列出了OSF / 1,SunOS,Solaris,HP-UX;我认为它应该适用于Hurd并适用于Linux)。
但是还有gprof的BSD实现(检查历史和引用的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/。两种变体都不支持OSX中使用的Mach-O格式。
在Darwin的cctools中甚至还有Apple自己的gprof(基于来自NetBSD / OpenBSD的BSD gprof)(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版本/包;根据{{3}}或2012年的某些版本 - http://louise.hu/poet/gprof-on-osx/或甚至2001年,有10.6.1的gprof:https://rachelbythebay.com/w/2012/09/14/mac/
在命令行中有使用instruments
(Xcode Tools的一部分?)的变体,不知道具体如何,但要知道这些乐器是现代且功能丰富的分析器。
还有iprofiler
命令行界面来收集Instruments.app
的配置文件,只是它的人工页面http://lists.apple.com/archives/darwin-development/2001/Apr/msg00617.html(Xcode Tools 5.0版的一部分;来自网站遗留部分的手册页) )。
有第三方分析器,声明支持OSX。我知道其中两个:valgrind和gperftools(google-perftools)。
valgrind不是探查者;它是一个(慢速)动态检测平台,其上构建了许多工具。它包含两个能够进行性能分析的工具:callgrind
和cachegrind
。 Valgrind和这两个工具都不是本机分析器,它们不会分析应用程序,因为它将在现实生活中的真实CPU上运行。相反,valgrind在虚拟机上执行程序,callgrind / cachegrind仪器用计数器执行机器代码。
callgrind(https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man1/iprofiler.1.html)使用每个线性指令块的计数器来计算"每条指令执行的次数" (" Ir"事件,用于获取配置文件 - 按所用时间百分比排序功能);它还记录调用/返回以构建调用图。 " IR"事件计数是正确的,以获得指令执行计数(它也可以模拟分支预测);但它不能用于估计实际运行时间。真正的cpu(高性能cpu称为超标量;乱序cpus也是超标量)能够在每个CPU时钟周期内执行多条指令;并且它通常也无法执行任何指令,因为它们可能需要启动一些数据(来自远程缓存或来自内存或来自系统调用或来自其他高延迟指令的数据;或cpu误预测分支导致指令地址尚未读取/解码)。大多数进步的cpus甚至可能不会执行某些命令(有些命令可以执行最多8" nop
" s每个周期,几个英特尔的Sandy / Ivy Bridges和更新的将不会花费任何时间on" xor eax,eax
"将零写入寄存器;它们只是将下一个寄存器使用重新映射到归零的物理寄存器)。与硬件CPU上的实际运行相比,callgrind的分析运行速度通常为10-20。
Cachegrind实现与callgrind相同的检测(" Ir",分支),但也可以模拟缓存层次结构(缓存加载/存储/未命中事件)。它比callgrind慢。
可以使用GUI工具kcachegrind(http://valgrind.org/docs/manual/cl-manual.html,它可以在OS中工作)或命令行工具callgrind_annotate
查看来自callgrind和cachegrind的输出。
其他工具是gperftools(google-perftools,http://kcachegrind.sourceforge.net/),它在真实CPU上运行程序。要使用它,请使用自制软件安装它,然后使用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`)。
答案 1 :(得分:-1)
关于我的一个问题(CrazyPython),我能够在@osgx的帮助下使用gperftools(pprof
)。 Here是问题,here是脚本的GitHub要点。为方便起见,这里是脚本内联:
#!/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
警告:我试着稍微清理一下。它可能包含很多不必要的选项。