views:

271

answers:

3

I'm moving my C++ codebase from Visual Studio 2k3 to Visual Studio 2k8. Code contains

#pragma optimize( "a", on )

MSDN says that it means "assume no aliasing". Later versions of VS refuse to compile this and MSDN doesn't seem to say what to do with code containing this #pragma.

What does "assume no aliasing" mean and how to I make a decision on what to do with this line of code?

+5  A: 

Aliasing is when you have stuff like this:

int a[100];

int * p1 = &a[50];
int * p2 = &a[52];

Now a, p1 and p2 are all aliases for the array, or parts of it. This situation can prevent the compiler from producing optimal array access code (FORTRAN forbids it, which is why it is so good with array performance).

The pragma you are asking about says that the compiler can assume the above situation doesn't exist. Obviously, if you need to decide whether you need this you can do one of two things:

  • check all your code (difficult and error prone)
  • turn it off and see if there is any performance degradations (easy and sensible)

The choice is yours :-)

anon
I really don't get how the above stuff prevent the compiler from generating faster code.
sharptooth
It's all about what values the compiler can cache in registers - a bit like the volatile issue.
anon
@sharptooth: The compiler doesn't always know about the aliasing - e.g. when a, p1 and p2 are passed into a function. Without "assume no aliasing", a modification through p1 would invalidate all cached data about a and p2, requiring memory reads instead of register reads.
peterchen
A: 

MSDN define the aliasing as the use of multiple names that refer to the same memory location.

The #pragma directive used to control this optimization in VS.NET has disappeared since VS.2005.

It seems that the __restrict keyword and restrict and noalias __declspec modifiers, used to annotate variables and functions, could do the same job.

cedrou
+3  A: 

Adding to what Neil said:

With the pragma you make a guarantee to the compiler that aliasing does nto occur, allowing additonal optimizations that are not possible for "standard" code.

To port: remove the pragma, then compare the run time of the VC7 and the VC9 build. If the VC9 build performs adequately, you are done.

Otherwise, if the VC9 build is significantly slower, compare the VC7 build without the #pragma to the VC9 build. If the additional optimizations are the cause of the speed difference, the VC7 build should now be slowed down to the VC9 build.

If that's the case, look into the __restrict / __declspec(noalias) declarations, and specifically the non-aliased references in the affected code block. Use a profiler to find the differences between the code.

Otherwise, the speed difference is not related to the #pragma.

peterchen
Of course, whether restrict/noalias is a good idea or or not is a famous bone of contention Dennis Ritchie was violently opposed to it - see http://www.lysator.liu.se/c/dmr-on-noalias.html
anon
@Neil: thanks for the link - interesting read. I didn't expect noalias to act as a type qualifier (which sounds scary as is already).
peterchen
Does someone know how much the noalias DMR speak about -- at the time of normalization of *C89*, noalias wasn't put in C89 -- is different of the restrict introduced in C99?
AProgrammer