Sign in to follow this  
broady

Performance with different compilers

Recommended Posts

broady    119
Hello gd people,
i had my c++/opengl project running fine on CodeBlocks (with MINGW compiler). The debugger but was not so handly so i decided to move all the code in VS2010 Express edition.

The code is for the 99.9% the same. The 0.1% difference comes from stuff that compiles on CB and not in VS and i had to change.

My program is a win32 project. In the strarting it has to do lot of calcs because it has to build a mesh representing an image. The mesh is a complex object containing members like stl Vectors of pointers to vertices, edges, faces etc...

Why the hell when i run the program in VS it takes much longer respect to CB? Of course i run everything in release. Once the mesh is builded i cant notice any different in performance.
But at the start, before the first image appears in the drawning window, we speak of 1-2 seconds in CB versus 10-15 seconds in VS.
Might be express edition the problem?

Thanks fellows!
Riziero

Share this post


Link to post
Share on other sites
Hodgman    51220
By default, MSVC generates debug-safety code for STL containers (even in release builds), which makes iterating over them (and other operations) excessively slow.

In your projects properties, you want to add the definitions:
[font="'Courier New"]_SCL_SECURE_NO_WARNINGS[/font]
[font="'Courier New"]_SECURE_SCL=0[/font]

Share this post


Link to post
Share on other sites
AndyEsser    394
[quote name='BitMaster' timestamp='1309950516' post='4831721']
Are you running a debug or release build when you measure those times?
[/quote]

He did say he's running in Release when measuring the times.

I would go with Hodgmans suggestion.

Share this post


Link to post
Share on other sites
broady    119
[quote name='AndyEsser' timestamp='1309952415' post='4831730']
[quote name='BitMaster' timestamp='1309950516' post='4831721']
Are you running a debug or release build when you measure those times?
[/quote]

He did say he's running in Release when measuring the times.

I would go with Hodgmans suggestion.
[/quote]

Thanks for fast reply.
I will try when i am back to homeand let you khnow :D

Share this post


Link to post
Share on other sites
zacaj    667
Thats pretty wierd. Without even adding that setting, my speed in VC2010 is about 3x codeblocks when both are in the default release modes

Share this post


Link to post
Share on other sites
SiCrane    11839
[quote name='Hodgman' timestamp='1309950450' post='4831720']
By default, MSVC generates debug-safety code for STL containers (even in release builds), which makes iterating over them (and other operations) excessively slow.

In your projects properties, you want to add the definitions:
[font="'Courier New"]_SCL_SECURE_NO_WARNINGS[/font]
[font="'Courier New"]_SECURE_SCL=0[/font]
[/quote]
Actually, that only applies to MSVC 2005 and 2008. In MSVC 2010 _SECURE_SCL is disabled by default in release builds. Also, _SCL_SECURE_NO_WARNINGS has no performance impact.

Share this post


Link to post
Share on other sites
Andrew Kabakwu    941
[quote name='Hodgman' timestamp='1309950450' post='4831720']
By default, MSVC generates debug-safety code for STL containers (even in release builds), which makes iterating over them (and other operations) excessively slow.

In your projects properties, you want to add the definitions:
[font="Courier New"]_SCL_SECURE_NO_WARNINGS[/font]
[font="Courier New"]_SECURE_SCL=0[/font]
[/quote]

How do you do this? Under which section?

Share this post


Link to post
Share on other sites
broady    119
[quote name='_Unicron_' timestamp='1309965124' post='4831813']
How are you running your app? If from within the IDE make sure you use CTRL-F5 (start without debugging) as opposed to just F5 (Debug).
[/quote]

Thanks mate it worked. Where is defined the CTRL+F5 shortcut?
Thanks a lot.

EDIT: if i build and run my project from outside the ide its equal to launching with CTRL+F5 from inside VS?

Share this post


Link to post
Share on other sites
_Unicron_    438
[quote name='broady' timestamp='1309971708' post='4831870']
Thanks mate it worked. Where is defined the CTRL+F5 shortcut?
Thanks a lot.
[/quote]

You can see if in the Debug drop-down menu. Or do you mean where is the keyboard mapping defined? If so :

Tools->Customize, Click the keyboard button. Scroll down to Debug.StartWithoutDebugging in the next window and you can see the keyboard shortcut and change it if you wish.


[quote name='broady' timestamp='1309971708' post='4831870']
EDIT: if i build and run my project from outside the ide its equal to launching with CTRL+F5 from inside VS?
[/quote]

Yes

Share this post


Link to post
Share on other sites
taz0010    277
Is your startup code very heavy on memory allocation? Some parts of my program incur almost twice as much overhead within the IDE in release mode due to the debug allocators (which are only used when running inside the IDE, so don't worry).

Also are you compiling with SSE extensions and the floating point model set to fast? The default settings (no SSE, fp:precise) are extremely slow (factor of 4-5x) when doing heavy work with floating point values.

Share this post


Link to post
Share on other sites
Cambo_frog    855
[quote name='broady' timestamp='1309995970' post='4832020']
yes i was expecting to see ctrl+F5 in the debug menu. Its not there, at least by default.
[/quote]

It should be. The menu item is titled " Start Without Debugging Ctrl + F5".

I have pro version of VS2010, but I can't see it being any different in the express version.

Share this post


Link to post
Share on other sites
Antheus    2409
[quote]The code is for the 99.9% the same.[/quote]The code you see is 99% the same. In reality, your entire codebase represents the 0.01%. The first large invisible part is standard library aka the STL, which is compiler specific and implemented independently. Then there is compiler itself. Final unknown is the operating system. Depending on what gets linked and how, resulting executable could be using different parts of OS. One reason for this might be that MSVC will be up to date with latest "secure" versions while gcc-based ones would use older versions.

But as far as low hanging fruit goes:

The heuristics of std::vector implementation (and other containers) differ between MSVC and gcc. One of likely causes would be not sizing them at the beginning. Additional resizing could add to performance issues. This may require some code change, but tends to be biggest algorithmic gain. Preallocating can result in up to factor of 10 improvement in some cases.

Another factor would be how operator new/malloc are implemented. MSVC's was improved over time, but it does not strictly prioritize running time. If there are many allocations, this would be lead to overall increase in running times. If you use new frequently for small objects (<16 bytes), then gcc is likely to behave better. MSVC and underlying WinAPI syscalls do not prioritize small allocations by default. It depends on choice of containers.

std::string and vector in MSVC are coded (IIRC) slightly more defensively, so they tend to have bulkier operations. While they were algorithmically better, there are many cases where they could take longer than GCC equivalent. I don't know if this is still true.

Share this post


Link to post
Share on other sites
broady    119
[quote name='Antheus' timestamp='1310042423' post='4832233']
[quote]The code is for the 99.9% the same.[/quote]The code you see is 99% the same. In reality, your entire codebase represents the 0.01%. The first large invisible part is standard library aka the STL, which is compiler specific and implemented independently. Then there is compiler itself. Final unknown is the operating system. Depending on what gets linked and how, resulting executable could be using different parts of OS. One reason for this might be that MSVC will be up to date with latest "secure" versions while gcc-based ones would use older versions.

But as far as low hanging fruit goes:

The heuristics of std::vector implementation (and other containers) differ between MSVC and gcc. One of likely causes would be not sizing them at the beginning. Additional resizing could add to performance issues. This may require some code change, but tends to be biggest algorithmic gain. Preallocating can result in up to factor of 10 improvement in some cases.

Another factor would be how operator new/malloc are implemented. MSVC's was improved over time, but it does not strictly prioritize running time. If there are many allocations, this would be lead to overall increase in running times. If you use new frequently for small objects (<16 bytes), then gcc is likely to behave better. MSVC and underlying WinAPI syscalls do not prioritize small allocations by default. It depends on choice of containers.

std::string and vector in MSVC are coded (IIRC) slightly more defensively, so they tend to have bulkier operations. While they were algorithmically better, there are many cases where they could take longer than GCC equivalent. I don't know if this is still true.
[/quote]

Thanks for your time it's a good reading.


Share this post


Link to post
Share on other sites
Aressera    2919
I'm having a similar issue with the sound propagation simulation library I'm developing: Compiling with GCC under Xcode I'm getting around 50fps, while when compiling using MSVC it runs at around 37fps. I'm dual-booting the same computer and compiling with all optimizations turned on in release mode for both platforms. I tried the 'run without debugging' option and didn't notice any improvement. My project doesn't make any use of STL so I can't blame different implementations. I'll also note that I'm heavily using the __forceinline directives for each compiler, so I don't think that it could be differences in inlining strategies.

Could it be that GCC's optimizer is better than MSVC's? Does anyone have any ideas for how I could improve the performance of my system when compiling using MSVC? I suppose I could always use GCC to compile under windows if I had to...

Share this post


Link to post
Share on other sites
Antheus    2409
[quote name='Aressera' timestamp='1310062951' post='4832407']
I'll also note that I'm heavily using the __forceinline directives for each compiler[/quote]

There is next to no reason to use any kind of inline indications anymore. The heuristics behind optimizing compilers these days make them obsolete and forcing inlines will typically do more harm than not.

When it comes to inlining, the much more productive route is to understand why branching and function calls cost and how to avoid them. A typical example is:[code]
if (not_enough_space(current, max)) {
resize(2*max);
}
add_element(...);[/code]

Unfortunately, this tends to be the default and most sensible way containers are written. But it goes against CPU-friendly code flow. Branches should prefer to take the common path as default, whereas resizing of container will be not only the undesired path but also something that will run at most n times.

The alternative might behave better:[code]
if (has_enough_room()) {
add_element();
return;
}
resize(2*max);
add_element();[/code]An important observation here is that add_element might or might not be inlined. Having smaller code that takes expected path might run better despite potentially having extra function calls.

It is effectively impossible for a human to perform inlining optimizations on today's CPUs. And definitely ban use of forced inlining, It can do no good, at most it will offer minimal improvement on a microbenchmark but preventing or harming the bigger picture.

Even at this level, algorithm trumps micro optimizations. Algorithms merely refer to how CPU works rather than what C++ code says.


Also, we're bikeshedding again, this type of optimizations are not done in real world.

[quote]Could it be that GCC's optimizer is better than MSVC's?[/quote]No. gcc is generally worse than any of other commercial compilers. But, the compiler differences amount to a single-digit percent in performance. Losing 25% at application is unlikely.

[quote]Does anyone have any ideas for how I could improve the performance of my system when compiling using MSVC? I suppose I could always use GCC to compile under windows if I had to...[/quote]
#1 cause - difference in drivers. I've experienced a factor of 50 difference on same machine, simply due to drivers.

Since the project is portable it likely uses OGL. Some Windows drivers have abysmal OGL support.

Share this post


Link to post
Share on other sites
Aressera    2919
Ok, so I tried compiling in MSVC with regular inlining and saw a small but negligible performance drop. It can't be an OpenGL driver issue because I've isolated the timing for graphics/sound simulation so I only get the time reported for the sound portion (I'm not doing anything graphically intensive anyway). The sound stuff is totally isolated from any system libraries (most of the time is spent doing ray tracing). I even tried changing the floating point model to fpfast and trying different optimization option but to no avail.

I think I might try compiling with GCC under windows and see if that makes any difference.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this