Profiling c++ on mac os x
Asked Answered
W

4

86

I'm attempting to profile some c++ code on my mac (os x Lion) and I haven't been able to find anything useful. I'm looking for a profiler that will tell me what functions are taking up my cpu time (similar to the matlab profiler).

Here is what I have tried

  • gprof. This is what I use on my linux machine, but it just gives me empty output on my mac (apparently a known problem)
  • Instruments. I can't for the life of me figure out how to profile anything within my compiled binary. Nor can I find any sort of useful tutorial.
  • (other searching revealed Shark, which is no longer available and Valgrind which is for memory).
Walkabout answered 12/7, 2012 at 5:42 Comment(5)
You might try this, for these reasons.Musette
MikeDunlavey's comment is obliquely suggesting that you open your program in gdb (or some other debugger, if you can figure out how) and manually interrupt it at periodic intervals, basically simulating what gprof/Instruments would do for you but with more mental strain. Just use Instruments instead; see @duskwuff's answer below for step-by-step instructions.Cadmarr
@Quuxplusone: My oblique suggestion finds speedup opportunities that gprof/Instruments do not. Instruments samples the call stack, but as near as I can tell it does not let you actually examine individual stack samples, which is how you find the speedups. Rather (unless I'm mistaken) it buys into the concept of "hot path", and in non-toy programs of any decent size, big problems can easily hide from the hot path.Musette
@Quuxplusone: Here's how to build the hot path. Take all the samples going through main (100%). Of those, find the routine most-called from main, (call it A) and suppose it is on 30% of the samples. Other functions could be on the other 70%, but each called less than A. Of those samples, find the routine most-called from A (call it B), and suppose it is on 30% of those samples. OK, so the sequence main-A-B is on 30% times 30% = 9% of the samples. Anything outside that 9% is not noticed. You can tell that after a few levels, there's a lot you don't see.Musette
iprofiler from BSD is nice since its output can be opened in Instruments.Observe
P
130

Instruments is the tool to use. A full explanation of Instruments is outside the scope of this answer, but here's a quick start guide:

  1. Open Instruments.1
  2. Select the "Time Profiler" template.
  3. Select your application in the "Target" dropdown menu.2
  4. Hit the red circle ("record") button to start your application running.
  5. If applicable, do some stuff in your application that you need to profile.
  6. Hit the record button again to stop recording.
  7. Use the tools in Instruments to analyze your results.

Of the tools available, the ones that will be most frequently useful are:

  • Expanding the call tree using the disclosure arrows
  • Clicking the circled arrow on a function name to focus it
  • Double-clicking a function to view the associated source
  • The "Invert Call Tree" checkbox on the left-hand side

You can also start an invocation of instruments on the command line:

instruments -l 30000 -t Time\ Profiler -p 5773

see instructions.


1 One easy way to open Instruments is to use Spotlight: Just click on the magnifying glass in the upper right corner of the taskbar (next to the clock) and type "Instruments".

2 Click "Choose Target..." and navigate to the path of your executable.

Pampa answered 12/7, 2012 at 5:58 Comment(8)
Hi @duskwuff, that is exactly what I have been doing, but my Stack-Trace is empty. There is absolutely nothing there. my application is a command-line tool that should terminate after about 30seconds, however Instruments just continues. Also I can't seem to find any command line output (not that it's necessary, but it would be a good indication that my program is running)Walkabout
Hrm… you can also try setting the target to "all processes", then launching your program manually in a terminal while Instruments is running. It'll let you fish out the data for your program from everything else it sampled; just click the circle-arrow on the name of your tool in the results.Pampa
FYI, I just learned about the iprofiler CLI tool to collect traces that can be viewed using the Instruments app. It isn't easy to discover it since man -k profiler doesn't include it in the results.Pandemic
This can also be used from the commandline, as instruments. For example, instruments -t "Time Profiler" ./a.out foo.txt 20 — this is easier than setting arguments and working directory in the GUI. After this, the resulting instrumentscli0.trace can be opened via the Instruments GUI, or even that (opening in the GUI) can be done via the commandline: open -a Instruments instrumentscli0.traceRepublicanize
Hello from 2022. I'm running on macOS 12.1 and cannot find the command line program instruments. Any idea where Apple moved it?Stoddard
@Stoddard It's in the "XCode" menu on the toolbar "Open Developer Tool" submenu. Next to the iOS Simulator if you've used that before.Cockaleekie
@PatKilg: I think @vy2 is looking for the instruments command line tool as referenced above (I am looking for it too, without any success so far).Carrigan
In 2022 try xctrace record --template 'Time Profiler' --launch <target>Ostraw
K
9

Instruments really is the right answer, but if you can't figure out how to use it then another option is the profiler in the built-in Activity Monitor application. In Activity Monitor you can get info on any running process and there's a button to sample its execution for a while. You'll have to start your program, switch to Activity Monitor, find the process, and then sample it.

Additionally you can do 'poor man's profiling' simply by running the program in a debugger and pausing it manually half a dozen times or so and noting the call stack at those times. It's very simple but it works surprisingly well as a first pass for a significant fraction of programs.

There is also a command line sample program which samples the callstack like the others do.

Kathernkatheryn answered 15/3, 2013 at 20:1 Comment(0)
E
9

Instruments is the tool to use. To overcome the issue of the blank traces, make sure that you open Instruments from within XCode:

Xcode > Open Developer Tool > Instruments

If you open Instruments from an old Instruments icon that you pinned to your dock before the last update to XCode, it will give you blank traces.

Eck answered 4/12, 2014 at 23:1 Comment(2)
Indeed. That solved the blank call tree issue for me. Thank you!Parimutuel
This appears to be the only way to launch Instruments now (other than the command line of course). It doesn't show up in spotlight anymore after recent OS upgrades. Not sure when that changed.Shortcake
T
2

In 2024,

'instruments' is now deprecated in favor of 'xcrun xctrace'.

So to profile your c++ excutable on MacOS as follow:

  1. Ensure you turn on debug symbols, for more information in the call graph. When compiling source code, add options -g for gcc/clang.

For example, I use xmake to build my project, then I add

set_symbols("debug")

in my xmake.lua config file.

If using cmake one may try

cmake --build . --target ALL_BUILD --config RelWithDebInfo
  1. After generate the binary excutable, run:
xctrace record --output . --template "Time Profiler" --time-limit 5s --launch -- <your_excutable_file> <excutable_args>

Previous command will generate a .trace file in current working directory, open file manager and double click to see the call graph.


Note: for more information, type xctrace help record in your terminal.

Teakettle answered 6/6, 2024 at 18:13 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.