Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What can human beings make out of the restrict qualifier?

If I got the C99 restrict keyword right, qualifying a pointer with it is a promise made that the data it references won't be modified behind the compiler's back through aliasing.

By contrast, the way I understand the const qualifier is as compiler-enforced documentation that a given object won't be modified behind the back of a human being writing code. The compiler might get a hint as a side effect, but as a programmer I don't really care.

In a similar way, would it be appropriate to consider a restrict qualifier in a function prototype as a requirement that the user ensures exclusive access ("avoid aliasing", or maybe something stronger) for the duration of the call? Should it be used as "documentation"?

Also, is there something to understand in the fact that restrict qualifies a pointer rather than the data it points to (as const does) ?

EDIT: I originally believed that restrict could have implications with threaded code, but this seems wrong so I remove references to threads from the question to avoid confusing readers.

like image 426
Jérémie Koenig Avatar asked Oct 01 '09 22:10

Jérémie Koenig


People also ask

What is restrict keyword used for?

restrict keyword is mainly used in pointer declarations as a type qualifier for pointers. It doesn't add any new functionality. It is only a way for programmer to inform about an optimization that compiler can make.

What does the restrict keyword do in C?

In the C programming language, restrict is a keyword, introduced by the C99 standard, that can be used in pointer declarations. By adding this type qualifier, a programmer hints to the compiler that for the lifetime of the pointer, no other pointer will be used to access the object to which it points.


2 Answers

Chris Dodd has the correct description of the keyword. In certain platforms it can be very important for performance reasons, because it lets the compiler know that once it has loaded data through that pointer onto a register, it need not do so again. Without this guarantee, the compiler must reload the data through a pointer every time any other possibly-aliasing pointer is written through, which can cause a serious pipeline stall called a load-hit-store.

const and restrict are different concepts, and it is not the case that const implies restrict. All const says is that you will not write through that pointer within the scope of that function. A const pointer may still be aliased. For example consider:

int foo( const int *a, int * b )
{
   *b *= 2;
   return *a + *b; // induces LHS: *a must be read back immediately
                   // after write has cleared the store queue
}

While you cannot directly write to a in this function, it would perfectly legal for you to call foo like:

int x = 3;
foo( &x, &x );  // returns 12

restrict is a different guarantee: a promise that a != b in all calls to foo().

I've written about the restrict keyword and its performance implications at length, and so has Mike Acton. Although we talk about a specific in-order PowerPC, the load-hit-store problem exists on the x86 as well, but the x86's out-of-order execution makes that stall harder to isolate in a profile.

And just to emphasize: this is not an arcane or premature optimization, if you care about performance at all. restrict can lead to really significant speedups if used correctly.

like image 184
Crashworks Avatar answered Nov 16 '22 00:11

Crashworks


The best 'intuition' to have about the restrict keyword is that its a guarantee (by the programmer to the compiler) that, for the lifetime of the pointer, memory accessed via that pointer will ONLY be accessed via that pointer and not via another pointer or reference or global address. So its important that its on a pointer as its a property of both the pointer and the memory, tying the two together until the pointer goes out of scope.

like image 26
Chris Dodd Avatar answered Nov 16 '22 00:11

Chris Dodd