FREE Subscription to Dr. Dobb’s Digest: Same Great Content, New Digital Edition
Site Archive (Complete)
C++
Email
Print
Reprint

add to:
Del.icio.us
Digg
Google
Furl
Slashdot
Y! MyWeb
Blink
July 01, 1999

Restricted Pointers are Coming

(Page 2 of 3)
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; }

Previous Page | 1 | 2 | 3 Next Page
RELATED ARTICLES
No Related Articles
TOP 5 ARTICLES
No Top Articles.



MICROSITES
FEATURED TOPIC

ADDITIONAL TOPICS

INFO-LINK