VS2008 Optimiser

Started by
5 comments, last by cache_hit 13 years, 9 months ago
The optimiser in VS2008 seems to be lacking when it comes to detecting common sub-expressions. Some examples are:

foo[bar]->a = x0;
foo[bar]->b = x1;
foo[bar]->c = x2;

The compiler was calculating foo[bar] at every point I used it, instead of performing this simple optimisation:

ObjType& fooBar = foo[bar];
fooBar.a = x0;
fooBar.b = x1;
fooBar.c = x2;

Also annoying is that most of the time the compiler won't cache the size() method of STL containers. When not using iterators, I usually write loops like this now:
for(std::size_t i = 0, num = vec.size(); i != num; i++)
The compiler ignores all the obvious signs that the size of the vector isn't changing. e.g. it doesn't matter if I'm only reading from the vector, and everything is marked const. It still spits out around 8 instructions every time size() is called.

Now for a question about practices. Are you guys in the habit of collecting sub-expressions yourselves - i.e. creating a reference to something you'll use more than once, such as foo[bar]->x, or do you consider this needless premature optimisation?
Advertisement
Quote:Original post by taz0010
Now for a question about practices. Are you guys in the habit of collecting sub-expressions yourselves - i.e. creating a reference to something you'll use more than once, such as foo[bar]->x, or do you consider this needless premature optimisation?


Rarely. Only in some inner loops and when there's a bottleneck/slowdown.
Quote:Original post by taz0010
The compiler was calculating foo[bar] at every point I used it, instead of performing this simple optimisation:

That is because foo[bar] can change in other thread while you are changing a member. So there is possibility that membe b needs to assigned for different foo object. Non-standard restrict keyword could help there.

Quote:When not using iterators, I usually write loops like this now:

You should prefer iterators.
Quote:Original post by taz0010

The compiler was calculating foo[bar] at every point I used it, instead of performing this simple optimisation:

Did you disable secure iterators?
Are you making a release build?
Quote:Original post by bubu LV
Quote:Original post by taz0010
The compiler was calculating foo[bar] at every point I used it, instead of performing this simple optimisation:

That is because foo[bar] can change in other thread while you are changing a member. So there is possibility that membe b needs to assigned for different foo object.
I don't believe other threads are taken into account unless volatile is specified.

I'm wondering what compiler flags are in use, first of all.
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
Well, I'm assuming foo is a std::vector in your example, so the optimization you're asking for isn't as straightforward as you make it out to be. Just because it looks like simple array indexing, it isn't.
ObjType &fooBar = foo[bar];// ...is really the same as...ObjType &fooBar = foo.at(bar);
So the optimization you're asking for would require the compiler to be able to examine the function and determine that the same input ALWAYS maps to the same output. If foo is actually a simple pointer, not a std::vector, then you're probably using the wrong build settings to get that optimization.

P.S. Your examples in the OP don't jive. The first one uses a dereferencing accessor (->), meaning foo would consist of an array of ObjType pointers, whereas the second one would consist of an array of ObjType. So it's kinda hard to tell what the exact situation is.
Quote:Original post by Promit
Quote:Original post by bubu LV
Quote:Original post by taz0010
The compiler was calculating foo[bar] at every point I used it, instead of performing this simple optimisation:

That is because foo[bar] can change in other thread while you are changing a member. So there is possibility that membe b needs to assigned for different foo object.
I don't believe other threads are taken into account unless volatile is specified.

I'm wondering what compiler flags are in use, first of all.


I believe other threads can be taken into account if the variable is global or if it is passed to an external library function.

I'm actually wondering what the complete function looks like. It could also be that the compiler can't tell whether or not the array is aliased, in which case performing the optimization would be broken.

This topic is closed to new replies.

Advertisement