title: Beyond Stack Sampling: C++ Profilers
body: <h1>A Hacker's Tale</h1>
  
  <p>The date is 12/02/10.  The days before Christmas are dripping away and I've pretty much hit a major road block as a windows programmer.  I've been using AQTime, I've tried sleepy, shiny, and very sleepy, and as we speak, VTune is installing.  I've tried to use the VS2008 profiler, and it's been positively punishing as well as often insensible.  I've used the random pause technique.  I've examined call-trees.  I've fired off function traces.  But the sad painful fact of the matter is that the app I'm working with is over a million lines of code, with probably another million lines worth of third-party apps.</p>
  
  <p>I need better tools.  <em>I've read the other topics.</em>  I've tried out each profiler listed in each topic.  There simply has to be something better than these junky and expensive options, or ludicrous amounts of work for almost no gain.  To further complicate matters, our code is heavily threaded, and runs a number of Qt Event loops, some of which are so fragile that they crash under heavy instrumentation due to timing delays.  Don't ask me why we're running multiple event loops.  No one can tell me.</p>
  
  <p>Are there any options more along the lines of Valgrind in a windows environment?<br>
  Is there anything better than the long swath of broken tools I've already tried?<br>
  Is there anything designed to integrate with Qt, perhaps with a useful display of events in queue?   </p>
  
  <p>A full list of the tools I tried, with the ones that were really useful in italics:</p>
  
  <ul>
  <li><em>AQTime:</em> Rather good!  Has some trouble with deep recursion, but the call graph is correct in these cases, and can be used to clear up any confusion you might have.  Not a perfect tool, but worth trying out.  It might suit your needs, and it certainly was good enough for me most of the time.</li>
  <li><em>Random Pause attack in debug mode:</em> Not enough information enough of the time.<br>
  A good tool but not a complete solution.</li>
  <li><em>Parallel Studios:</em>  The nuclear option.  Obtrusive, weird, and crazily powerful.  I think you should hit up the 30 day evaluation, and figure out if it's a good fit. It's just darn cool, too.</li>
  <li><em>AMD Codeanalyst:</em>  Wonderful, easy to use, very crash-prone, but I think that's an environment thing.  I'd recommend trying it, as it is free.</li>
  <li><em>Luke Stackwalker:</em> Works fine on small projects, it's a bit trying to get it working on ours.  Some good results though, and it definitely replaces Sleepy for my personal tasks.</li>
  <li><em>PurifyPlus:</em> No support for Win-x64 environments, most prominently Windows 7.  Otherwise excellent.  A number of my colleagues in other departments swear by it.</li>
  <li>VS2008 Profiler: Produces output in the 100+gigs range in function trace mode at the required resolution.  On the plus side, produces solid results.</li>
  <li>GProf: Requires GCC to be even moderately effective.</li>
  <li>VTune: VTune's W7 support borders on criminal. Otherwise excellent</li>
  <li>PIN: I'd need to hack up my own tool, so this is sort of a last resort.</li>
  <li>Sleepy\VerySleepy: Useful for smaller apps, but failing me here.</li>
  <li>EasyProfiler: Not bad if you don't mind a bit of manually injected code to indicate where to instrument.</li>
  <li>Valgrind: *nix only, but very good when you're in that environment.</li>
  <li>OProfile: Linux only.</li>
  <li>Proffy: They shoot wild horses.</li>
  </ul>
  
  <p>Suggested tools that I haven't tried:  </p>
  
  <ul>
  <li>XPerf:  </li>
  <li>Glowcode:  </li>
  <li>Devpartner:  </li>
  </ul>
  
  <p><strong>Notes:</strong>
  Intel environment at the moment.  VS2008, boost libraries.  Qt 4+.  And the wretched humdinger of them all: Qt/MFC integration via trolltech.
  <hr/>
  <strong>Now:</strong> Almost two weeks later, it looks like my issue is resolved.  Thanks to a variety of tools, including almost everything on the list and a couple of my personal tricks, we found the primary bottlenecks.  However, I'm going to keep testing, exploring, and trying out new profilers as well as new tech.  Why?  Because I owe it to you guys, because you guys rock.  It does slow the timeline down a little, but I'm still very excited to keep trying out new tools.</p>
  
  <p><strong>Synopsis</strong><br>
  Among many other problems, a number of components had recently been switched to the incorrect threading model, causing serious hang-ups due to the fact that the code underneath us was suddenly no longer multithreaded.  I can't say more because it violates my NDA, but I can tell you that this would never have been found by casual inspection or even by normal code review.  Without profilers, callgraphs, and random pausing in conjunction, we'd still be screaming our fury at the beautiful blue arc of the sky.  Thankfully, I work with some of the best hackers I've ever met, and I have access to an amazing 'verse full of great tools and great people.</p>
  
  <p>Gentlefolk, I appreciate this tremendously, and only regret that I don't have enough rep to reward each of you with a bounty.  I still think this is an important question to get a better answer to than the ones we've got so far on SO.  </p>
  
  <p>As a result, each week for the next three weeks, I'll be putting up the biggest bounty I can afford, and awarding it to the answer with the nicest tool that I think isn't common knowledge.  After three weeks, we'll hopefully have accumulated a definitive profile of the profilers, if you'll pardon my punning.</p>
  
  <p><strong>Take-away</strong><br>
  Use a profiler.  They're good enough for Ritchie, Kernighan, Bentley, and Knuth. I don't care who you think you are.  Use a profiler.  If the one you've got doesn't work, find another.  If you can't find one, code one.  If you can't code one, or it's a small hang up, or you're just stuck, use random pausing.  If all else fails, hire some grad students to bang out a profiler.</p>
  
  <p><hr/>
  <strong>A Longer View</strong><br>
  So, I thought it might be nice to write up a bit of a retrospective.  I opted to work extensively with Parallel Studios, in part because it is actually built on top of the PIN Tool.  Having had academic dealings with some of the researchers involved, I felt that this was probably a mark of some quality.  Thankfully, I was right.  While the GUI is a bit dreadful, I found IPS to be incredibly useful, though I can't comfortably recommend it for everyone.  Critically, there's no obvious way to get line-level hit counts, something that AQT and a number of other profilers provide, and I've found very useful for examining rate of branch-selection among other things.  In net, I've enjoyed using AQTime as well, and I've found their support to be really responsive.  Again, I have to qualify my recommendation:  A lot of their features don't work that well, and some of them are downright crash-prone on Win7x64.  XPerf also performed admirably, but is agonizingly slow for the sampling detail required to get good reads on certain kinds of applications.  </p>
  
  <p>Right now, I'd have to say that I don't think there's a definitive option for profiling C++ code in a W7x64 environment, but there are certainly options that simply fail to perform any useful service.</p>