1

One of the big differences between C/C++ and Fortran when it comes to speed is that the former languages use pointers which can be aliased and therefore a compiler needs to load in the data at each loop iteration while Fortran's allocatable does not have that problem.

C offers the keyword restrict so you ensure the compiler that the pointer is not being aliased. With c++, the standard does not offer this option. I am not willing to use a vendor extension since I am concerned about portability, but also this is a critical part of my application. Hence, I don't won't to rely on things outside standard when they are fundamental to my app.

QUESTION

My question is if there is a way to ensure the c++ compiler that a specific pointer argument is not being aliased. Will C++ reference be of any help (i.e. having references as arguments pass by value is not an option since we are dealing with very large arrays)?, or should I simply write those routines in C and calling them from my C++ app?

  void HEAVY_CALC( double *p1, double *p2 , double *p3, int n1)
  {
     
       for(int i = 0; i<n1 ; i ++ ) {
           p1[i] = Func_1( ) ; 
           p2[i] = Func_2( ) ;  
           p3[i]= Func_3( ) ;  
       }
     
  }

Since pointers here could be alised by others compiler will load p1,p2,p3 at each i iteration. In C if I add restrict that will be resolved. What happens if I add a reference instead of pointer i.e.

    void HEAVY_CALC( double* &p1, double *&p2 , double* &p3, int n1)

Would that change anything?

ATK
  • 1,296
  • 10
  • 26
  • 1
    Could you show a [mre] of some code you are trying to optimise? – Alan Birtles Jul 10 '20 at 11:35
  • Okay I will try to show a very simple example – ATK Jul 10 '20 at 11:36
  • 1
    Aaaand that's why C++ compilers support `__restrict` keyword as an extension. Even on [wiki](https://en.wikipedia.org/wiki/Restrict) it says `C++ does not have standard support for restrict, but many compilers have equivalents that usually work in both C++ and C` and `__restrict is supported by those three compilers.` (ie. gcc clang msvc) – KamilCuk Jul 10 '20 at 11:36
  • 1
    Yes, I know this, but the idea of this question was whether there was another way to enforce this without having to go beyond the standard. – ATK Jul 10 '20 at 11:37
  • 1
    related: https://stackoverflow.com/questions/22724980/why-is-the-restrict-keyword-not-part-of-c – 463035818_is_not_an_ai Jul 10 '20 at 11:38

1 Answers1

2

[Is] there is a way to [promise] the [C++] compiler that a specific pointer argument is not being aliased [..] without having to go beyond the standard[?]

No, there isn't.

You can usually use the non-standard __restrict instead, which was introduced to major toolchains to plug exactly this gap. Portability isn't such a concern here as you might think, since GCC, Clang and Visual Studio all deliberately support the same keyword.

Allegedly, it's not trivial to add restrict to the language, even though such a keyword has (as indicated above) been shown to be completely implementable. Indeed, it's been done already.

Asteroids With Wings
  • 17,071
  • 2
  • 21
  • 35
  • Thanks. Would a reference to a pointer change the picture of the alias problem, just out of curiousity? – ATK Jul 10 '20 at 11:49
  • 1
    @A2LBK I don't see why it would. – Asteroids With Wings Jul 10 '20 at 11:49
  • 3
    `__restrict` provides a subset of what `restrict` does in C. Presumably, some part or parts of the functionality `restrict` not provided by `__restrict` is difficult for compilers to implement in C++. – Peter Jul 10 '20 at 11:50
  • 1
    @Peter That's only true in VS. For GCC and Clang, `__restrict` is exactly the same as C's `restrict`. Feel free to click on some of the links I've provided for more information on this feature. – Asteroids With Wings Jul 10 '20 at 11:50
  • Nice answer. Funny how the standards committee decided that user defined literals were more important than introducing `restrict`. – Bathsheba Jul 10 '20 at 11:53
  • @Bathsheba Indeed – Asteroids With Wings Jul 10 '20 at 11:56
  • One problem with `restrict` is that the way the term "based upon" is defined in C99 creates absurd, ambiguous, and unworkable corner cases. If the definition specified a transitive "definitely based upon" relation, and only forbade aliasing between pointers that were definitely based on P, and those that were definitely based upon something that was definitely not based upon P, that would have made it both easier to process correctly and much more useful for programmers. – supercat Jul 10 '20 at 15:39