C++ Profiling

Started by
7 comments, last by LorenzoGatti 17 years, 4 months ago
After finding that Visual Studio 2005 Professional doesn't appear to contain a profiler, I got a copy of LTProf for shareware. However there are two linked problems: 1)If I don't use the debug build of my app, the majority of the function/method calls are not listed in the profiling analysis. 2)If I use the debug build, the timings are not very useful because I use a lot of STL, and STL is horrendously slow in debug builds. So, is there any way around this? And is there a better profiler that's free? How can they get away without including one in VS - seems you have to buy the Team version for a profiler! I tried writing my own:
	map<string,pair<__int64,int> > CallData;
	class ASMTimer
	{
	public:
		ASMTimer(string &name) : Name(name)
		{
			++CallData[Name].second;
			Start=__rdtsc();
		}
		~ASMTimer()
		{
			End=__rdtsc();
			CallData[Name].first+=End-Start;
		}
	private:
		unsigned __int64 Start,End;
		string Name;
	};
You use it like:
class::method()
{
ASMTimer Timer("Class::Method");
...
}
Of course it's basic but it seems reasonably OK. I wonder if I'm better off using this?
Advertisement
1. msvc only includes a profiler as part of team system
2. the "problem" with release builds is that the compiler is very likely to optimize away unused paths of your code: your profiler won't be able to collect any samples at all. you need to make sure you don't have "artificial" applications that don#t actually use the code in your libraries/objects.. simple example: if you don't use the return value of an intensive computation the compiler is free to optimize away the call to this function. The result is that the function doesn't execute, samples aren't collected.
btw either use amd's codeanalyst or the community edition of devpartners' profiler.
Quote:Original post by Anonymous Poster
2. the "problem" with release builds is that the compiler is very likely to optimize away unused paths of your code: your profiler won't be able to collect any samples at all. you need to make sure you don't have "artificial" applications that don#t actually use the code in your libraries/objects.. simple example: if you don't use the return value of an intensive computation the compiler is free to optimize away the call to this function. The result is that the function doesn't execute, samples aren't collected.


I have no idea what this person is talking about, but please ignore the post. The whole point of actually profiling an optimized build is to determine what's actually being executed.

As to the OP - yes, simple manual profiling like what you posted can be very useful. However, it's not a substitue for "real" profiling, it's an additional data point.

You may be able to use profiling on your release build if you enable the storing of debug information - how to do that varies by compiler & version.
Quote:Original post by JasonBlochowiak
As to the OP - yes, simple manual profiling like what you posted can be very useful. However, it's not a substitue for "real" profiling, it's an additional data point.

You may be able to use profiling on your release build if you enable the storing of debug information - how to do that varies by compiler & version.
I already had debug information enabled in my release build. It saw one call into my class and then all the calls within the class were missed out. I don't know why!

Without seeing your code...

It is possible that all the other calls within your test class have been inlined, in which case they will not generate coverage/profiler hits.

And what the AP said was actually quite relevant. The VC++ optimizer will very aggressively remove code where the final result is never used. This makes it quite challenging to profile the behaviour of single classes in isolation because you eventually do nothing with the result. There is an option to generate a file with a side-by-side view of your C++ code with the generated assembly code which can be helpful to figure out what's going on.
Quote:Original post by JasonBlochowiak
Quote:Original post by Anonymous Poster
2. the "problem" with release builds is that the compiler is very likely to optimize away unused paths of your code: your profiler won't be able to collect any samples at all. you need to make sure you don't have "artificial" applications that don#t actually use the code in your libraries/objects.. simple example: if you don't use the return value of an intensive computation the compiler is free to optimize away the call to this function. The result is that the function doesn't execute, samples aren't collected.


I have no idea what this person is talking about, but please ignore the post. The whole point of actually profiling an optimized build is to determine what's actually being executed.


He's actually making a valid point. If you try profiling a piece of code that, for example, just tests merging two structures together and then discarding the merged result, the compiler may well remove all that code entirely, seeing that it has no effect on the rest of the program. So in release mode it is best to profile your proper code, not artificial test cases that may get optimised away.
Quote:Original post by Kylotan
Quote:Original post by JasonBlochowiak
Quote:Original post by Anonymous Poster
2. the "problem" with release builds is that the compiler is very likely to optimize away unused paths of your code: your profiler won't be able to collect any samples at all. you need to make sure you don't have "artificial" applications that don#t actually use the code in your libraries/objects.. simple example: if you don't use the return value of an intensive computation the compiler is free to optimize away the call to this function. The result is that the function doesn't execute, samples aren't collected.


I have no idea what this person is talking about, but please ignore the post. The whole point of actually profiling an optimized build is to determine what's actually being executed.


He's actually making a valid point. If you try profiling a piece of code that, for example, just tests merging two structures together and then discarding the merged result, the compiler may well remove all that code entirely, seeing that it has no effect on the rest of the program. So in release mode it is best to profile your proper code, not artificial test cases that may get optimised away.


I see - I guess the notion of profiling something that's not relevant to performance was alien enough that I hadn't considered doing it. :)
I'd rather profile the aggressively optimized production version, because its performance on a realistic workload is the true objective of optimization; any artificial test that exercises code that is mostly unused or often optimized away is intrinsically irrelevant.
The seldom used parts of the code need only be tested for correctness: only the functions at the top of the profiler timing list for realistic tests, or those that cause timeout errors or other latency problems, deserve optimization.

Omae Wa Mou Shindeiru

This topic is closed to new replies.

Advertisement