10

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?

Puppy
  • 144,682
  • 38
  • 256
  • 465
vkubicki
  • 1,104
  • 1
  • 11
  • 26
  • 7
    Regarding GCC's `-fno-strict-aliasing`, you have it backwards. The option cause the compiler to worry that some aliases may exist. By default, it assumes that these aliases do not exist. – Pascal Cuoq Sep 04 '11 at 10:31
  • The cases where the `restrict` keyword matters are pretty rare actually, and it is usually pretty obvious where it matters. [This document](http://cellperformance.beyond3d.com/articles/2006/05/demystifying-the-restrict-keyword.html) is quite informative, and emphasizes the fact that the order of loads and stores matter too. But as I said before, the cases where you will use such optimization are quite obvious to spot. – Alexandre C. Sep 04 '11 at 10:53
  • I don't think `GCC` has anything similar to [Intel's option `-fno-alias`](https://software.intel.com/en-us/cpp-compiler-developer-guide-and-reference-falias-oa) (Which basically is equivalent of annotating each pointer by the `restrict` annotation). I actually wish it did. – Royi May 01 '20 at 18:58
  • The compiler cannot vectorize an array loop if aliasing cannot be ruled out. __restrict is often necessary for vectorizing array loops. – A Fog Aug 07 '22 at 06:58

1 Answers1

17

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.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • I think your analysis is right: this is exactly the kinds of spots `restrict` was introduced for. See also http://cellperformance.beyond3d.com/articles/2006/05/demystifying-the-restrict-keyword.html for additional details, including how to write a function using `restrict` pointers to hint the compiler about how to schedule loads and stores. – Alexandre C. Sep 04 '11 at 10:59
  • 1
    This answer is very instructive but does not answer the question. I have a hard time believing there is no equivalent to -fnoalias other than manually adding "restrict" everywhere in your application – Saiph Nov 14 '19 at 15:46
  • 1
    I think the OP was talking about aliasing of 2 different pointers pointing to the same address which is a case which prevents optimization. While GCC flag is about alising of types, not addresses. Unless I read the documentation wrong. – Royi May 01 '20 at 14:20