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