Skip to main content
gamedev.net
🔒 Locked

VS2005 optimization problem

Started by rozz666 Oct 15, 2008 at 12:02 PM 10 replies 2k views
Original Post
rozz666
rozz666
I've made a simple profiler that measures the time between entering a scope and leaving it:

class ProfileScope {
public:
    ProfileScope(...) { // start measurement }
    ~ProfileScope() { // stop measurement }
};
It accesses global variables. It's used like:

void f()
{
   ProfileScope xxx("f() scope");
   //...
}
The problem is that VS optimizes the destruction of xxx and does it right after creation or maybe later but 100% not at the end of the scope. Is there a way to prevent it?
Sneftel
Sneftel
That sounds extremely strange. Order of variable construction/destruction is very important, and unlikely to be touched by the optimizer where there are side effects. What's an example of the actual code which demonstrated this? (The real actual code, not a summary or a rewrite)
rozz666
rozz666
Unfortunately I can't supply the original code because of NDA, but that's just what I have written. It 2 calls global object's methods: startSample(const std::string& name, int id) and stopSample(int d). It has a map inside it. The problem I was having was that I was measuring a function which took a lot of time and only called some other functions. Now the time it spent in each function was almost 0. Argument copying etc. was not important. When I switched to Debug it started to measure time properly. Unfortunately measuring performance under Debug Mode doesn't makes much sense.
Sneftel
Sneftel
Not much better help I can give you. Several libraries, such as Boost.Thread, use exactly this sort of thing to provide scoped functionality, and it works fine regardless of optimization settings. IMHO it's extremely unlikely that the problem is related to the optimizer reordering construction/destruction order as you believe.
Spoonbender
Spoonbender
Have you verified in the debugger that it actually executes the destructor too early?

Otherwise, a more likely explanation is that the timer you're using has limited resolution, so it returns unexpected values (If it has a resolution of 10ms, and the block of code you're profiling only takes 3ms, it may return 0ms or something)

Run it in the debugger and verify that it runs the destructor where it's supposed to.
rozz666
rozz666
Quote:
Original post by Spoonbender
Have you verified in the debugger that it actually executes the destructor too early?

Otherwise, a more likely explanation is that the timer you're using has limited resolution, so it returns unexpected values (If it has a resolution of 10ms, and the block of code you're profiling only takes 3ms, it may return 0ms or something)

Run it in the debugger and verify that it runs the destructor where it's supposed to.


It's not the timer problem. The functions take a few seconds in release so it's not a resolution problem.
In Debug mode mode it works. In Release I haven\t debug it. I'll check it tomorrow .

Is there a way to force the VS2005 not optimize it?
Spoonbender
Spoonbender
Quote:
Original post by rozz666
Is there a way to force the VS2005 not optimize it?


There might be a #pragma to disable optimization for individual functions, but once again, this is not the problem. What you're doing is so common in C++ that if the compiler incorrectly optimized it, almost any piece of software written in C++ would break.

Feel free to disable optimizations, but you'd only hide the problem, not solve it.
iMalc
iMalc
Compiled the following new project in release build of VS2005 Express:
#include "stdafx.h"class ProfileScope {public:    ProfileScope() { printf("Constructor\n"); }    ~ProfileScope() { printf("Destructor\n"); }};void f(){	ProfileScope p;	printf("In f() body\n");}int _tmain(int argc, _TCHAR* argv[]){	f();	return 0;}
Output:
ConstructorIn f() bodyDestructor
Same behaviour in debug mode.

Until you can provide code that disproves this behaviour, we have no reason to believe otherwise.
To find out what is really happening one has to look at the real code, so you're on your own if you can't post it. I will say this though: Question your assumptions
DerekSaw
DerekSaw
Maybe in release build, somewhere in between throws an exception?
"after many years of singularity, i'm still searching n the event horizon" o
Adam_42
Adam_42
The one thing that has caught me out when writing code like that is forgetting to give the variable a name - using "ProfileScope("whatever");" instead of "ProfileScope ps("whatever");".

The first version will create and destroy the object on the same line of code and give close to zero time elapsed. It's even worse when it's a scoped critical section because it will work most of the time using either method...
iMalc
iMalc
Quote:
Original post by Adam_42
The one thing that has caught me out when writing code like that is forgetting to give the variable a name - using "ProfileScope("whatever");" instead of "ProfileScope ps("whatever");".

The first version will create and destroy the object on the same line of code and give close to zero time elapsed. It's even worse when it's a scoped critical section because it will work most of the time using either method...
Actually now that you mention it, I'd say that would be the problem, except for the fact that he claims it works in a debug build.

I did exactly this myself a few months back with an ObjectLock, but fortunately it was spotted in a code review.
rozz666
rozz666
Thanks for the ideas, but I'm not forgetting to create a variable instead of a temporary and no exception is being thrown. I used the code many times with no problems under Borland Turbo C++. I use a high resolution timer. Tomorow I'll try to debug it in release mode.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.