Having recently read that the main reason why fortran is faster than c/c++ in numerical computations is because there is no pointer aliasing.
Apparently, using restrict
or __restrict__
keywords allows on a case by case basis to indicate the absence of pointer aliasing for a given memory element.
The icc compiler apparently has an option -fno-alias
which allows one to globally assume that no aliasing is present. On gcc there is -fno-strict-aliasing
, which applies only to a subset of all the aliasing situations.
Is there an option present in gcc, or are there some cases where no aliasing is assumed, when using certain optimization flags?
In C, C++, and some other programming languages, the term aliasing refers to a situation where two different expressions or symbols refer to the same object.
Pointer aliasing is a hidden kind of data dependency that can occur in C, C++, or any other language that uses pointers for array addresses in arithmetic operations. Array data identified by pointers in C can overlap, because the C language puts very few restrictions on pointers.
GCC compiler makes an assumption that pointers of different types will never point to the same memory location i.e., alias of each other. Strict aliasing rule helps the compiler to optimize the code.
An alias occurs when different variables point directly or indirectly to a single area of storage. Aliasing refers to assumptions made during optimization about which variables can point to or occupy the same storage area.
GCC has the option -fstrict-aliasing
which enables aliasing optimizations globally and expects you to ensure that nothing gets illegally aliased. This optimization is enabled for -O2
and -O3
I believe.
C++ has well defined aliasing rules, though, and standard-compliant code will not conflict with strict aliasing. In particular this means you're not allowed to access one variable through a pointer to a different type:
float f;
int * p = reinterpret_cast<int*>(&f); // uh-oh
*p = 0x3FF00000; // breaks strict aliasing
The crucial exception to this rule is that you can always access any variable through a pointer to char
. (This is necessary for serializing through IO operations.)
The aliasing rules do not help the compiler to know whether any pointers of the same type alias each other. Consider this:
void add(float * a, float * b, float * c) { *c = *a + *b; }
Here the compiler cannot know whether c
points to different memory than a
or b
and has to be careful. I think this is where restrict
makes a difference, essentially by promising that float * restrict c
means that nobody aliases c
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With