Channels ▼
RSS

Restricted Pointers are Coming


July 1999/Restricted Pointers are Coming/Listing 1

Listing 1: A test for compiler support of restrict

/* 
 * This program is legal C and C++, except for the use of 
 * restrict. The abuses of restrict are deliberately illegal.
 * Some compilers, such as the DEC Alpha cc compiler, recognize
 *  __restrict instead of restrict.  Others such as KAI C++ 
 * require the option --restrict. 
 */
#include <stdio.h>
     
#define N 1000
     
#ifdef USE_UNDERSCORE
#define restrict __restrict 
#endif /* USE_UNDERSCORE */
     
/* BODY is the computation shared by all tests here. */
#define BODY int i; for( i=0; i<n; ++i ) \
    a[i] = (b[j+N/4] + b[j-N/4]) * 0.5f;
     
float * wash( float * ptr );    /* forward declaration */
     
/* Base line version without restrict */
void simple( float * a, float * b, int n, int j ) {
    BODY
}
     
/* 
 * Version with restrict on both formal parameters. 
 * If the compiler complains about the declaration, 
 * it probably does not understand restrict. 
 */
void 
with_restrict_formals( float * restrict a, float * restrict b, 
    int n, int j) {

    BODY
}
     
/* Version with restrict only on output pointer */
void 
with_restrict_out_formal( float * restrict a, float * b, 
    int n, int j ) {

    BODY
}
     
/* Version with restrict only on input pointer */
void 
with_restrict_in_formal( float * a, float * restrict b, 
    int n, int j ) {

    BODY
}
     
/* Version with restrict on pointers local to a block */
void 
with_restrict_local( float * ap, float * bp, int n, int j ) {

    float * restrict a = wash(ap);
    float * restrict b = wash(bp);
    BODY
}
     
/* Version with restrict on pointers, but work is done with 
   local copies of the pointers */
void 
with_local_copy_of_restrict_formals( float * restrict ap, 
    float * restrict bp, int n, int j ) {

    float * a = ap+n-N;
    float * b = bp+n-N;
    BODY
}
     
typedef 
void (*a_ptr_to_function)( float * a, float * b, int n, int j );
     
#define ENTRY(x) {#x,x}
     
struct {
    char * name;
    a_ptr_to_function ptr_to_function;
} table[] = {
    ENTRY(simple),
    ENTRY(with_restrict_formals),
    ENTRY(with_restrict_out_formal),
    ENTRY(with_restrict_in_formal),
    ENTRY(with_restrict_local),
    ENTRY(with_local_copy_of_restrict_formals)
};
     
#define M (sizeof(table)/sizeof(table)[0])
     
/* 
 * Function report_differences compares results a and b. 
 *
 * A report of a few differences (2-4) probably indicates that 
 * the compiler exploited restrict for software pipelining, 
 * but not for invariant hoisting. 
 *
 * A report of about 3*N/4 differences probably indicates that 
 * the compiler exploited restrict for hoisting of invariants. 
 */
void 
report_differences( float * a, float * b, const char * name ) {
    int i;
    int current = -1;
    printf("%s:",name);
    for( i=0; i<=N; ++i ) 
        if( i==N || a[i]==b[i] ) {
            if( current>=0 ) {
                if( current!=i-1 ) printf("...%d", i-1 ); 
                current = -1;
            }
        } else {
            if( current<0 ) {
                printf(" %d", i );
                current = i;
            }   
        }
    printf("\n");
}
     
float array[M][N];
float* array_ptr[M];
     
/* 
 * The purpose of function "wash" is to return a pointer the 
 * same as "ptr", but in a way the disguises that the returned 
 * pointer really is the same. 
 */
float * wash( float * ptr ) {
    int j;
    for( j=0; ptr!=array[j]; ++j ) 
        continue;
    return array_ptr[j];
}
     
int main() {
    int i, j;
     
    /* Initialize data sets */
    for( j=0; j<M; ++j ) {
        array_ptr[j] = array[j];
        for( i=0; i<N; ++i ) {
            array[j][i] = i;
        }
    }
     
    /* Run each test */
    for( j=0; j<M; ++j ) {
        (*table[j].ptr_to_function)(array[j], array[j], N, N/2);
    }
     
    /* Report the errors - more is better! */ 
    for( j=1; j<M; ++j ) {
        report_differences( array[0], array[j], table[j].name );
    }
     
    return 0;
}


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 

Video