|
PAPI
5.3.0.0
|
00001 /* 00002 * File: data_range.c 00003 * Author: Dan Terpstra 00004 * terpstra@cs.utk.edu 00005 * Mods: <your name here> 00006 * <your email address> 00007 */ 00008 00009 /* This file performs the following test: */ 00010 /* exercise the Itanium data address range interface */ 00011 00012 #include "papi_test.h" 00013 #define NUM 16384 00014 00015 static void init_array( void ); 00016 static int do_malloc_work( long loop ); 00017 static int do_static_work( long loop ); 00018 static void measure_load_store( caddr_t start, caddr_t end ); 00019 static void measure_event( int index, PAPI_option_t * option ); 00020 00021 int *parray1, *parray2, *parray3; 00022 int array1[NUM], array2[NUM], array3[NUM]; 00023 char event_name[2][PAPI_MAX_STR_LEN]; 00024 int PAPI_event[2]; 00025 int EventSet = PAPI_NULL; 00026 00027 int 00028 main( int argc, char **argv ) 00029 { 00030 int retval; 00031 const PAPI_exe_info_t *prginfo = NULL; 00032 const PAPI_hw_info_t *hw_info; 00033 00034 /* Set TESTS_QUIET variable */ 00035 tests_quiet( argc, argv ); 00036 00037 #if !defined(ITANIUM2) && !defined(ITANIUM3) 00038 test_skip( __FILE__, __LINE__, "Currently only works on itanium2", 0 ); 00039 exit( 1 ); 00040 #endif 00041 00042 tests_quiet( argc, argv ); /* Set TESTS_QUIET variable */ 00043 00044 init_array( ); 00045 printf( "Malloc'd array pointers: %p %p %p\n", &parray1, &parray2, 00046 &parray3 ); 00047 printf( "Malloc'd array addresses: %p %p %p\n", parray1, parray2, 00048 parray3 ); 00049 printf( "Static array addresses: %p %p %p\n", &array1, &array2, 00050 &array3 ); 00051 00052 tests_quiet( argc, argv ); /* Set TESTS_QUIET variable */ 00053 00054 if ( ( retval = 00055 PAPI_library_init( PAPI_VER_CURRENT ) ) != PAPI_VER_CURRENT ) 00056 test_fail( __FILE__, __LINE__, "PAPI_library_init", retval ); 00057 00058 hw_info = PAPI_get_hardware_info( ); 00059 if ( hw_info == NULL ) 00060 test_fail( __FILE__, __LINE__, "PAPI_get_hardware_info", 2 ); 00061 00062 prginfo = PAPI_get_executable_info( ); 00063 if ( prginfo == NULL ) 00064 test_fail( __FILE__, __LINE__, "PAPI_get_executable_info", 1 ); 00065 00066 #if defined(linux) && defined(__ia64__) 00067 sprintf( event_name[0], "loads_retired" ); 00068 sprintf( event_name[1], "stores_retired" ); 00069 PAPI_event_name_to_code( event_name[0], &PAPI_event[0] ); 00070 PAPI_event_name_to_code( event_name[1], &PAPI_event[1] ); 00071 #else 00072 test_skip( __FILE__, __LINE__, "only works for Itanium", PAPI_ENOSUPP ); 00073 #endif 00074 00075 if ( ( retval = PAPI_create_eventset( &EventSet ) ) != PAPI_OK ) 00076 test_fail( __FILE__, __LINE__, "PAPI_create_eventset", retval ); 00077 00078 retval = PAPI_cleanup_eventset( EventSet ); 00079 if ( retval != PAPI_OK ) 00080 test_fail( __FILE__, __LINE__, "PAPI_cleanup_eventset", retval ); 00081 00082 retval = PAPI_assign_eventset_component( EventSet, 0 ); 00083 if ( retval != PAPI_OK ) 00084 test_fail( __FILE__, __LINE__, "PAPI_assign_eventset_component", 00085 retval ); 00086 00087 /***************************************************************************************/ 00088 printf 00089 ( "\n\nMeasure loads and stores on the pointers to the allocated arrays\n" ); 00090 printf( "Expected loads: %d; Expected stores: 0\n", NUM * 2 ); 00091 printf 00092 ( "These loads result from accessing the pointers to compute array addresses.\n" ); 00093 printf 00094 ( "They will likely disappear with higher levels of optimization.\n" ); 00095 00096 measure_load_store( ( caddr_t ) & parray1, ( caddr_t ) ( &parray1 + 1 ) ); 00097 measure_load_store( ( caddr_t ) & parray2, ( caddr_t ) ( &parray2 + 1 ) ); 00098 measure_load_store( ( caddr_t ) & parray3, ( caddr_t ) ( &parray3 + 1 ) ); 00099 /***************************************************************************************/ 00100 printf 00101 ( "\n\nMeasure loads and stores on the allocated arrays themselves\n" ); 00102 printf( "Expected loads: %d; Expected stores: %d\n", NUM, NUM ); 00103 00104 measure_load_store( ( caddr_t ) parray1, ( caddr_t ) ( parray1 + NUM ) ); 00105 measure_load_store( ( caddr_t ) parray2, ( caddr_t ) ( parray2 + NUM ) ); 00106 measure_load_store( ( caddr_t ) parray3, ( caddr_t ) ( parray3 + NUM ) ); 00107 /***************************************************************************************/ 00108 printf( "\n\nMeasure loads and stores on the static arrays\n" ); 00109 printf 00110 ( "These values will differ from the expected values by the size of the offsets.\n" ); 00111 printf( "Expected loads: %d; Expected stores: %d\n", NUM, NUM ); 00112 00113 measure_load_store( ( caddr_t ) array1, ( caddr_t ) ( array1 + NUM ) ); 00114 measure_load_store( ( caddr_t ) array2, ( caddr_t ) ( array2 + NUM ) ); 00115 measure_load_store( ( caddr_t ) array3, ( caddr_t ) ( array3 + NUM ) ); 00116 /***************************************************************************************/ 00117 00118 retval = PAPI_destroy_eventset( &EventSet ); 00119 if ( retval != PAPI_OK ) 00120 test_fail( __FILE__, __LINE__, "PAPI_destroy", retval ); 00121 00122 free( parray1 ); 00123 free( parray2 ); 00124 free( parray3 ); 00125 00126 test_pass( __FILE__, NULL, 0 ); 00127 00128 exit( 1 ); 00129 } 00130 00131 static void 00132 measure_load_store( caddr_t start, caddr_t end ) 00133 { 00134 PAPI_option_t option; 00135 int retval; 00136 00137 /* set up the optional address structure for starting and ending data addresses */ 00138 option.addr.eventset = EventSet; 00139 option.addr.start = start; 00140 option.addr.end = end; 00141 00142 if ( ( retval = PAPI_set_opt( PAPI_DATA_ADDRESS, &option ) ) != PAPI_OK ) 00143 test_fail( __FILE__, __LINE__, "PAPI_set_opt(PAPI_DATA_ADDRESS)", 00144 retval ); 00145 00146 measure_event( 0, &option ); 00147 measure_event( 1, &option ); 00148 } 00149 00150 static void 00151 measure_event( int index, PAPI_option_t * option ) 00152 { 00153 int retval; 00154 long long value; 00155 00156 if ( ( retval = PAPI_add_event( EventSet, PAPI_event[index] ) ) != PAPI_OK ) 00157 test_fail( __FILE__, __LINE__, "PAPI_add_event", retval ); 00158 00159 if ( index == 0 ) { 00160 /* if ((retval = PAPI_get_opt(PAPI_DATA_ADDRESS, option)) != PAPI_OK) 00161 test_fail(__FILE__, __LINE__, "PAPI_get_opt(PAPI_DATA_ADDRESS)", retval); 00162 */ 00163 printf 00164 ( "Requested Start Address: %p; Start Offset: 0x%5x; Actual Start Address: %p\n", 00165 option->addr.start, option->addr.start_off, 00166 option->addr.start - option->addr.start_off ); 00167 printf 00168 ( "Requested End Address: %p; End Offset: 0x%5x; Actual End Address: %p\n", 00169 option->addr.end, option->addr.end_off, 00170 option->addr.end + option->addr.end_off ); 00171 } 00172 00173 retval = PAPI_start( EventSet ); 00174 if ( retval != PAPI_OK ) { 00175 test_fail( __FILE__, __LINE__, "PAPI_start", retval ); 00176 } 00177 do_malloc_work( NUM ); 00178 do_static_work( NUM ); 00179 retval = PAPI_stop( EventSet, &value ); 00180 if ( retval != PAPI_OK ) { 00181 test_fail( __FILE__, __LINE__, "PAPI_stop", retval ); 00182 } 00183 00184 printf( "%s: %lld\n", event_name[index], value ); 00185 00186 if ( ( retval = 00187 PAPI_remove_event( EventSet, PAPI_event[index] ) ) != PAPI_OK ) 00188 test_fail( __FILE__, __LINE__, "PAPI_remove_event", retval ); 00189 } 00190 00191 static void 00192 init_array( void ) 00193 { 00194 parray1 = ( int * ) malloc( NUM * sizeof ( int ) ); 00195 if ( parray1 == NULL ) 00196 test_fail( __FILE__, __LINE__, "No memory available!\n", 0 ); 00197 memset( parray1, 0x0, NUM * sizeof ( int ) ); 00198 00199 parray2 = ( int * ) malloc( NUM * sizeof ( int ) ); 00200 if ( parray2 == NULL ) 00201 test_fail( __FILE__, __LINE__, "No memory available!\n", 0 ); 00202 memset( parray2, 0x0, NUM * sizeof ( int ) ); 00203 00204 parray3 = ( int * ) malloc( NUM * sizeof ( int ) ); 00205 if ( parray3 == NULL ) 00206 test_fail( __FILE__, __LINE__, "No memory available!\n", 0 ); 00207 memset( parray3, 0x0, NUM * sizeof ( int ) ); 00208 00209 } 00210 00211 static int 00212 do_static_work( long loop ) 00213 { 00214 int i; 00215 int sum = 0; 00216 00217 for ( i = 0; i < loop; i++ ) { 00218 array1[i] = i; 00219 sum += array1[i]; 00220 } 00221 00222 for ( i = 0; i < loop; i++ ) { 00223 array2[i] = i; 00224 sum += array2[i]; 00225 } 00226 00227 for ( i = 0; i < loop; i++ ) { 00228 array3[i] = i; 00229 sum += array3[i]; 00230 } 00231 00232 return sum; 00233 } 00234 00235 static int 00236 do_malloc_work( long loop ) 00237 { 00238 int i; 00239 int sum = 0; 00240 00241 for ( i = 0; i < loop; i++ ) { 00242 parray1[i] = i; 00243 sum += parray1[i]; 00244 } 00245 00246 for ( i = 0; i < loop; i++ ) { 00247 parray2[i] = i; 00248 sum += parray2[i]; 00249 } 00250 00251 for ( i = 0; i < loop; i++ ) { 00252 parray3[i] = i; 00253 sum += parray3[i]; 00254 } 00255 00256 return sum; 00257 }