Author Topic: HUGE openGL frame rate difference between Code::Blocks and VS2005  (Read 8568 times)

Offline nestumkiller

  • Single posting newcomer
  • *
  • Posts: 5
Hi!

I've installed recently Code::Blocks and created a new project (not imported) - Win32App - getting some files that I already had in a VS2005.
After removing the #include <stdafx.h> of all of them, I compiled the code, run it and... a difference of +- 800FPS comparing to VS2005, yes, you read it correctly.
In VS2005 for the same code (the difference is mainly on the precompiled headers) I had 30FPS and now, when I run it on Code::Blocks: +-800FPS.
Somebody has an idea of what could make such a difference? It's incredible!! I would really appreciate to know something regarding that.
Thanks

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: HUGE openGL frame rate difference between Code::Blocks and VS2005
« Reply #1 on: April 25, 2006, 01:49:51 am »
Nobody will be able to tell for sure, but if you did not change any other code, it is probably a systemic error, not an actual speed improvement. It is not probable that gcc is 26 times faster than the MSVC compiler under the same conditions.

The most likely reason is you compared debug mode with vertical sync enabled against release mode without vsync.

Debug mode can be a lot slower than release, and it is well possible that you just get over the 16.6 ms per frame threshold, and pronto, you only draw on every other vblank = 30 fps.

As a sidenote, frames per second is a bad measure that you should not use. Frame times are much better as a measure since they are linear.
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

Offline nestumkiller

  • Single posting newcomer
  • *
  • Posts: 5
Re: HUGE openGL frame rate difference between Code::Blocks and VS2005
« Reply #2 on: April 25, 2006, 02:23:00 am »
Hi again!

Well, I also checked the release/debug part. In VS I was actually under debug mode. However, I did the same in Code::Blocks by generating debug information and putting a breakpoint (just to make sure :)). Regarding the vsync. I don't have single clue about it. How and where can it be enabled/disabled? Do you have any suggestion on where/how could I try to do some modifications in order to find the source of such a colossal difference?
Thanks for the tip about frame times.
BTW, since the code I'm using almost doesn't use openGL: it's some Lab code for a course Introduction To CG. So, I'm doing all the culling/shading/transformation "by hand". I only use openGL for the rendering, using simple primitives as glVertex with GL_LINES and GL_TRIANGLES. Could the bottleneck be around something else but openGL? Like STL usage, or other stuff?

Offline Vampyre_Dark

  • Regular
  • ***
  • Posts: 255
  • Hello!
    • Somewhere Over The Rainbow...
Re: HUGE openGL frame rate difference between Code::Blocks and VS2005
« Reply #3 on: May 04, 2006, 01:27:11 am »
VSync can be toggled on and off in your videocard settings. Or it can be toggled in GL using an extension ext_gl_swap_interval() I think (been awhile). But the driver can be set to overide this, so check your driver options first.

You can have an OpenGL app that just clears the screen running @ 1000fps, and then draw one triangle and drop to 100 fps. It doesn't mean anything. Wait until you are actually using the gfx card properly, and sending proper batches in the proper order to minimize state changes to see what your actual FPS is going to be.

Also, glVertex, glLines, and glTriangle ARE a bottleneck. Using these is what is known as immediate mode. It's slow, and it's not what you use when you are programming with performance in mind. You will use vertex arrays for that.

You will want to sort your data by shader/texture and set these once per batch. Then you send over a vertex array containing all the triangle data using that shader and texture. Then you stop, set the new shaders, textures and any other options, and send over all the triangles using those new options.

*I say triangles just to keep my example brief, it could be any primitive type...
« Last Edit: May 04, 2006, 01:28:49 am by Vampyre_Dark »
C::B Wishlist
~BOYCOTT THE EVIL YELLOW BOXES~

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: HUGE openGL frame rate difference between Code::Blocks and VS2005
« Reply #4 on: May 04, 2006, 10:19:23 am »
You can have an OpenGL app that just clears the screen running @ 1000fps, and then draw one triangle and drop to 100 fps. It doesn't mean anything.
That's why I said you should use frame times. Differences in frame times are much more meaningful and intuitive.

The reason why I suggested that VSync might be involved is that this is a common experience which baffles a lot of people. "Uh.... it just ran at 60 fps, and now it runs at 30 fps, I did not really change a lot, why does it drop to 50%?". The answer to this is that they had a frame time of maybe 16.5 ms before and 16.7 or 16.8 afterwards. If your monitor has a refresh of 60 Hz, one frame is 16.666 ms. If you are done before that time, you're fine. Otherwise, you'll wait for the next sync. Thus, even if your frame time only changes insignificantly, if it crosses the "magic border", then your frame rate will suddenly drop by 50%. Many people are surprised to see that happen, as it is not intuitive, but it is perfectly logical.

As Vampyre_Dark already said, it can be tricky to turn on/off vsync as the drivers may or may not allow you to. Speaking of driver preferences, you're sure that you did not inadvertedly turn on 16x antialiasing on one PC and none on the other, aren't you :)

Immediate mode calls are slow, granted. However, on reasonably recent hardware this does not matter too much (remember, you do not intend to program an action game). I've seen demos that draw surprisingly large scenes entirely in immediate mode and still obtain high frame rates (100-150 FPS). If you're just doing some teaching demo stuff, then putting a lot of time into vertex buffer objects and sorting objects for shaders and textures may be a waste of time.

Regarding your question on the STL, this highly depends on your usage. If you use the STL "correctly", then it should not matter too much, as both implementations probably use nearly the same algorithms and have comparable run times for the same operations.
However, it is of course possible that seemingly unimportant differences make a huge difference in extreme cases. The classical example for "stupid" STL usage in CG is to store vertices in a vector and do 1,000,000 push_back() operations each frame. In this case, a STL implementation that reallocates larger chunks of memory will be a *lot* faster (but you should of course not do that at all in the first place).

There are techniques to locate bottlenecks, both nVidia and ATI have papers on that.
The most obvious one is to use a profiler, if all your CPU time goes into some library that you don't know, then it is the OpenGL driver choking on your immediate mode calls :)
Another possibility is to use identical GPUs on different CPUs and vice versa.
A quick and easy way to check whether you're fillrate limited is to resize the window (unluckily, it is not that easy for all other bottlenecks).
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

Offline nestumkiller

  • Single posting newcomer
  • *
  • Posts: 5
Re: HUGE openGL frame rate difference between Code::Blocks and VS2005
« Reply #5 on: May 04, 2006, 01:09:42 pm »
Hi guys!
Thank you again for the huge :) explanations, but I think you're missing a little bit the issue. Since my source code was precisely (well, I just removed the windows precompiled headers - stdafx.h - so I could compile it on Code::Blocks) the same, and I didn't enable/disable VSync on my graphics card, then it shouldn't be related to that, right? I though the VSync belonged to some sort of option in VS or even Code::Blocks (I never used it before, so... :P), that's why I asked where I could enable/disable it. Nevertheless, I found it.
Another important issue, is that the code was run on same machine: a Asus laptop with a Centrino 1.7, 1Gb Ram, well, and most importantly, an ATI Radeon X700 128Mb (fully dedicated). What bugs me the most is, supposing the VSync hasn't changed for Code::Blocks or VS, what could make this huge differences?
Regarding the performance, well, obviously I try to make it work quicker. But the fact here, is that I'm having the course and lecturing it. And since it's a Introduction to CG everything is very unefficient and slow. But changing from 30FPS to 800FPS? My VSync option is set like this: Default Off - so it should be disabled for both VS and Code::Blocks, right?

Finally, and of big importance, I noticed some time ago, that a major bottleneck on VS was related to the usage of STL and push_backs, yada yada yada. So, I tried to improve it as much as I could (or I know). When I skipped all those calls, my FPS really increased. Then I changed to Code::Blocks... and Et Voilą :D

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: HUGE openGL frame rate difference between Code::Blocks and VS2005
« Reply #6 on: May 04, 2006, 02:14:48 pm »
Quote
major bottleneck on VS was related to the usage of STL and push_backs, yada yada yada. So, I tried to improve it as much as I could (or I know).
Yes, that's a common experience. STL is not free :)
It is quite possible, as mentioned before, that a slightly different STL implementation is significantly faster in extreme cases. In fact, if compiler and STL were really the only parameters that changed, then what else could it be :)

How can such gross differences between different STLs occur if they do the same thing?
For example, suppose both implementations start with a vector size of 5. One implementation reallocates in steps of n*1.5 elements, and the other in steps of n*2 elements. The implementation is not required to use a specific number, so the assumption that different implementations use different numbers is not unrealistic. Insignificant, one might say at first. Really?

What happens if you push_back 10000 elements? The first implementation would run this sequence:
5;8;11;17;25;38;57;85;128;192;288;432;649;973;1460;3284;4926;7389;11084.
while the other would run that one:
5;10;20;40;80;160;320;640;1280;2560;5120;10240
Remember that a new memory block is allocated and the whole dataset has to be copied every time. Allocations are slow, and worse, copying takes linear time.
Clearly, the second implementation will be a lot faster (even though it is still very, very inefficient).

Many people make claims like "the STL is evil" for reasons like the above. However, when people say that the STL is the problem, they are wrong almost every time. Rather, they are no using it correctly. For example, push_back is mostly harmless if you reserve appropriately. Actually, in that case, using vector is not any worse than using an array, only more comfortable and safer. Since you normally know the number of elements that you'll need (if not exactly, then at least approximately), that is usually not a problem.

Personally, I use STL a lot, and I bow to the people who wrote it. In almost every case, the STL is very close to or beats hand-written, optimised code, and you don't have to worry about the "hard stuff".
But one has to be aware that the functionality behind STL is no arcane magic, nor is it generally free. Especially when using containers in an inappropriate manner (or with inappropriate objects), the cost can be quite high. That's not a bug, though. That's due to design.
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

Offline mandrav

  • Project Leader
  • Administrator
  • Lives here!
  • *****
  • Posts: 4291
    • Code::Blocks IDE
Re: HUGE openGL frame rate difference between Code::Blocks and VS2005
« Reply #7 on: May 04, 2006, 02:23:03 pm »
Don't forget that the choice of the right container for the job is a major optimisation one could perform.
For example, if you 're going to use push_front() on a std::vector a lot, think again. std::deque might fit the job better...
What I mean is learn about all the available containers, their strengths and weaknesses, and choose wisely which one you want to use.
Be patient!
This bug will be fixed soon...

Offline Vampyre_Dark

  • Regular
  • ***
  • Posts: 255
  • Hello!
    • Somewhere Over The Rainbow...
Re: HUGE openGL frame rate difference between Code::Blocks and VS2005
« Reply #8 on: May 04, 2006, 02:47:59 pm »
Not sure if I maybe misunderstood thomas' whole meaning here, but immediate mode always makes a difference! It's the difference between 1 function call per batch, and 9+ for every triangle.

When I toggle my app between immediate mode and using arrays with just 4400 triangles, there is a HUGE difference. That's (4400 * 9) calls in the place of the just 6 calls it takes me to get m 6 different types of objects drawn. Immediate Mode in my scene still operates around 60~ fp, however, I'm not using shaders or any advanced extensions. Using arrays I get into the ~100-200fps zone.

The difference becomes less negligable as the polygon count increases, because more and more time is wasted waiting on immediate mode call overhead to feed data one by one, and the card isn't functioning the way it was meant to (for performace) which is to operate on 1 large batch.

Quote
That's why I said you should use frame times. Differences in frame times are much more meaningful and intuitive.
I agree. However, I say to wait, because people sometimes assume that after the initial drop in frames per second, that they will get an equal drop after every command they add. Which is not the case.

Here is a nice STL reference I have been using.
C::B Wishlist
~BOYCOTT THE EVIL YELLOW BOXES~


Offline Vampyre_Dark

  • Regular
  • ***
  • Posts: 255
  • Hello!
    • Somewhere Over The Rainbow...
Re: HUGE openGL frame rate difference between Code::Blocks and VS2005
« Reply #10 on: May 04, 2006, 03:04:52 pm »
Look interesting :).

I also find this one not bad at all:

http://www.sgi.com/tech/stl/

Best wishes,
Michael

:lol:
I like the one I was using because it was quicker to find the functions I was looking up when I was using vectors for the first time a few months ago.  :lol:
C::B Wishlist
~BOYCOTT THE EVIL YELLOW BOXES~

Offline killerbot

  • Administrator
  • Lives here!
  • *****
  • Posts: 5179
Re: HUGE openGL frame rate difference between Code::Blocks and VS2005
« Reply #11 on: May 04, 2006, 03:08:33 pm »
"smart use of stl is very important" otherwise you might have very surprising results. Last year I was at a C++ conference in Vegas, during that conference I followed a workshop from Scott Meyers on using the stl wisely.

He gave an example of a very stupid test case about strings, 10000 times 1 character was added to the string, no innitial reserve calls were made. The Gnu compiler/stl reallocated exponentially, but the M$ compiler/stl allocated linearly by an increlent of ...... "1".
It is for sure that in this scenario one will get very different performance results.


Offline killerbot

  • Administrator
  • Lives here!
  • *****
  • Posts: 5179
Re: HUGE openGL frame rate difference between Code::Blocks and VS2005
« Reply #12 on: May 04, 2006, 03:09:49 pm »
Look interesting :).

I also find this one not bad at all:

http://www.sgi.com/tech/stl/

Best wishes,
Michael

:lol:
I like the one I was using because it was quicker to find the functions I was looking up when I was using vectors for the first time a few months ago.  :lol:

for the non digital, paper prefering people : Jossutis's book on STL. Very good book to learn from and on the other hand a very good reference book.

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: HUGE openGL frame rate difference between Code::Blocks and VS2005
« Reply #13 on: May 04, 2006, 04:05:31 pm »
When I toggle my app between immediate mode and using arrays with just 4400 triangles, there is a HUGE difference. That's (4400 * 9) calls in the place of the just 6 calls it takes me to get m 6 different types of objects drawn. Immediate Mode in my scene still operates around 60~ fp, however, I'm not using shaders or any advanced extensions. Using arrays I get into the ~100-200fps zone.
There is another huge difference. Immediate mode is something you can explain to every computing noob. You can tell them: "look, it works like this, you have vertices and you build triangles from them". Everybody will understand. Talk to them about binding a vertex buffer, and no one will follow.
If you are teaching CG basics, you will want to show them some 3d objects and rotate them around, some texturing maybe, show off a few shaders, but that's it.
You don't write Doom 3. You don't need to calculate pathfinding, you don't need to evaluate whether or not a NPC will shoot at you, no music, no network, nothing of that kind.
Consequentially, you don't care whether you lose some performance to immediate mode, it is still good enough. 100 frames are not any better than 60. As long as you get more than 30 fps, the human eye is not aware of it. TV has 25 frames, and you don't see it. For demonstrating something in a teaching session that is absolutely ok (well, except if the session is about using vertex buffers... :)).

Apart from that, vertex buffers (or vertex arrays, likewise) are a lot harder to implement, as it is a lot less obvious what is going on, and you can easily crash your app if the slightest thing goes wrong.
In immediate mode, the worst case to happen is that some of your objects are not drawn :)

If you look at almost all of the well-known demo-tutorials that are available on the net, you will find that they are coded in immediate mode. It is very well possible to render a 129x129 height map (16k vertices) with dual texturing at 40-60 fps in immediate mode, as has been shown several times. 16k vertices is plenty.
Sure enough, you burn a lot of CPU in API calls, but so what. For what it is used, it is good enough.
« Last Edit: May 04, 2006, 04:07:27 pm by thomas »
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

Offline Michael

  • Lives here!
  • ****
  • Posts: 1608
Re: HUGE openGL frame rate difference between Code::Blocks and VS2005
« Reply #14 on: May 04, 2006, 04:34:04 pm »
Look interesting :).

I also find this one not bad at all:

http://www.sgi.com/tech/stl/

Best wishes,
Michael

:lol:
I like the one I was using because it was quicker to find the functions I was looking up when I was using vectors for the first time a few months ago.  :lol:

When I have begun with STL time ago for my project, I used the MSDN for quick access to list functions and examples. Later, I begin to use more and more the www.sgi.com/tech/stl/, because it gives useful explanations of the STL containers. Anyway, I still use occasionally MSDN or a google found website for easy access to the list of functions :).
 
Best wishes,
Michael