Jump to content

restrict

From Wikipedia, the free encyclopedia

This is an old revision of this page, as edited by Bitwiseb (talk | contribs) at 20:35, 15 May 2008 (Optimization: Possible bugfix...). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.


In the C programming language, as of the C99 standard, restrict is a keyword which may be used when declaring pointers. The restrict keyword is a message from the programmer to the compiler saying 'this is the only pointer to that memory block'. The data pointed to by a pointer declared with the restrict qualifier may not be pointed to by any other pointer, or strange runtime behavior may result.

Optimization

If the compiler knows that there is only one pointer to a memory block, it can produce better optimised code. The following example makes it clear:

void UpdatePtrs(size_t* ptrA, size_t* ptrB, size_t* val)
{
    *ptrA += *val;
    *ptrB += *val;
}

In the above code, the pointers ptrA , ptrB, val may refer to the same memory location, so the compiler will generate a less optimal code :

load R1  *val  ; Load the value of val pointer
load R2  *ptrA ; Load the value of ptrA ponter
add  R2 += R1   ; Perform Addition
set  R2  *ptrA ; Update the value of ptrA pointer
; Similarly for ptrB, note that val is loaded twice, 
; Because ptrA may point to val.
load R1  *val  
load R2  *ptrB
add  R2 += R1
set  R2  *ptrB

However if the restrict keyword is used and the above function is declared as void UpdatePtrs(size_t* restrict ptrA, size_t* restrict ptrB, size_t* restrict val) then the compiler knows that ptrA , ptrB, val point to different locations and updating one pointer will not affect the other pointers. Now the compiler can generate more optimal code as follows:

load R1  *val 
load R2  *ptrA
load R3  *ptrB
add  R2 += R1
add  R3 += R1
set  R2  *ptrA
set  R3  *ptrB

Note that the above assembly code is more optimal and the val is loaded once.

Another example is of memcpy. The two pointers used as arguments to memcpy(void*, void*, nbytes) are declared with restrict, which tells the compiler of the memcpy function that the two data areas do not overlap. This allows the compiler to produce a faster memcpy function. A programmer might send the same pointer as both arguments, in which case behavior of the memcpy function is undefined.