PAPI  5.0.1.0
cost.c
Go to the documentation of this file.
00001 
00033 #include "papi_test.h"
00034 #include "cost_utils.h"
00035 
00036 int 
00037 find_derived( int i , char *type)
00038 {
00039   PAPI_event_info_t info;
00040 
00041   PAPI_enum_event( &i, PAPI_ENUM_FIRST );
00042 
00043   do {
00044     if ( PAPI_get_event_info( i, &info ) == PAPI_OK ) {
00045       if ( strcmp( info.derived, type) == 0 )
00046         return i;
00047     }
00048   } while ( PAPI_enum_event( &i, PAPI_PRESET_ENUM_AVAIL ) == PAPI_OK );
00049 
00050   return PAPI_NULL;
00051 }
00052 
00053 /* Slight misnomer, find derived event != DERIVED_POSTFIX */
00054 int
00055 find_derived_add( int i ) 
00056 {
00057   int ret;
00058 
00059   if ( (ret = find_derived( i, "DERIVED_ADD")) != PAPI_NULL)
00060     return ret;
00061 
00062 
00063   return find_derived( i, "DERIVED_SUB"); 
00064 }
00065 
00066 int 
00067 find_derived_postfix( int i ) 
00068 {
00069   return ( find_derived ( i, "DERIVED_POSTFIX" ) );
00070 }
00071 
00072 static void
00073 print_help( void )
00074 {
00075     printf( "This is the PAPI cost program.\n" );
00076     printf
00077         ( "It computes min / max / mean / std. deviation for PAPI start/stop pairs; for PAPI reads, and for PAPI_accums.  Usage:\n\n" );
00078     printf( "    cost [options] [parameters]\n" );
00079     printf( "    cost TESTS_QUIET\n\n" );
00080     printf( "Options:\n\n" );
00081     printf
00082         ( "  -b BINS       set the number of bins for the graphical distribution of costs. Default: 100\n" );
00083     printf( "  -d            show a graphical distribution of costs\n" );
00084     printf( "  -h            print this help message\n" );
00085     printf
00086         ( "  -s            show number of iterations above the first 10 std deviations\n" );
00087     printf
00088         ( "  -t THRESHOLD  set the threshold for the number of iterations. Default: 100,000\n" );
00089     printf( "\n" );
00090 }
00091 
00092 
00093 static void
00094 print_stats( int i, long long min, long long max, double average, double std )
00095 {
00096     char *test[] = { "loop latency", "PAPI_start/stop (2 counters)",
00097         "PAPI_read (2 counters)", "PAPI_read_ts (2 counters)",
00098             "PAPI_accum (2 counters)", "PAPI_reset (2 counters)", 
00099             "PAPI_read (1 derived_postfix counter)"," PAPI_read (1 derived_[add|sub] counter)"
00100     };
00101     printf( "\nTotal cost for %s over %d iterations\n", test[i], num_iters );
00102     printf
00103         ( "min cycles   : %lld\nmax cycles   : %lld\nmean cycles  : %lf\nstd deviation: %lf\n ",
00104           min, max, average, std );
00105 }
00106 
00107 static void
00108 print_std_dev( int *s )
00109 {
00110     int i;
00111 
00112     printf( "\n" );
00113     printf
00114         ( "              --------# Standard Deviations Above the Mean--------\n" );
00115     printf
00116         ( "0-------1-------2-------3-------4-------5-------6-------7-------8-------9-----10\n" );
00117     for ( i = 0; i < 10; i++ )
00118         printf( "  %d\t", s[i] );
00119     printf( "\n\n" );
00120 }
00121 
00122 static void
00123 print_dist( long long min, long long max, int bins, int *d )
00124 {
00125     int i, j;
00126     int step = ( int ) ( max - min ) / bins;
00127 
00128     printf( "\nCost distribution profile\n\n" );
00129     for ( i = 0; i < bins; i++ ) {
00130         printf( "%8d:", ( int ) min + ( step * i ) );
00131         if ( d[i] > 100 ) {
00132             printf
00133                 ( "**************************** %d counts ****************************",
00134                   d[i] );
00135         } else {
00136             for ( j = 0; j < d[i]; j++ )
00137                 printf( "*" );
00138         }
00139         printf( "\n" );
00140     }
00141 }
00142 
00143 static void
00144 do_output( int test_type, long long *array, int bins, int show_std_dev,
00145            int show_dist )
00146 {
00147     int s[10];
00148     long long min, max;
00149     double average, std;
00150 
00151     std = do_stats( array, &min, &max, &average );
00152 
00153     print_stats( test_type, min, max, average, std );
00154 
00155     if ( show_std_dev ) {
00156         do_std_dev( array, s, std, average );
00157         print_std_dev( s );
00158     }
00159 
00160     if ( show_dist ) {
00161         int *d;
00162         d = calloc( bins , sizeof ( int ) );
00163         do_dist( array, min, max, bins, d );
00164         print_dist( min, max, bins, d );
00165         free( d );
00166     }
00167 }
00168 
00169 
00170 int
00171 main( int argc, char **argv )
00172 {
00173     int i, retval, EventSet = PAPI_NULL;
00174     int retval_start,retval_stop;
00175     int bins = 100;
00176     int show_dist = 0, show_std_dev = 0;
00177     long long totcyc, values[2];
00178     long long *array;
00179     int event;
00180     PAPI_event_info_t info;
00181 
00182 
00183     tests_quiet( argc, argv );  /* Set TESTS_QUIET variable */
00184 
00185     for ( i = 0; i < argc; i++ ) {
00186         if ( argv[i] ) {
00187             if ( strstr( argv[i], "-b" ) ) {
00188                 bins = atoi( argv[i + 1] );
00189                 if ( bins )
00190                     i++;
00191                 else {
00192                     printf( "-b requires a bin count!\n" );
00193                     exit( 1 );
00194                 }
00195             }
00196             if ( strstr( argv[i], "-d" ) )
00197                 show_dist = 1;
00198             if ( strstr( argv[i], "-h" ) ) {
00199                 print_help(  );
00200                 exit( 1 );
00201             }
00202             if ( strstr( argv[i], "-s" ) )
00203                 show_std_dev = 1;
00204             if ( strstr( argv[i], "-t" ) ) {
00205                 num_iters = ( int ) atol( argv[i + 1] );
00206                 if ( num_iters )
00207                     i++;
00208                 else {
00209                     printf( "-t requires a threshold value!\n" );
00210                     exit( 1 );
00211                 }
00212             }
00213         }
00214     }
00215 
00216     printf( "Cost of execution for PAPI start/stop, read and accum.\n" );
00217     printf( "This test takes a while. Please be patient...\n" );
00218 
00219     if ( ( retval =
00220            PAPI_library_init( PAPI_VER_CURRENT ) ) != PAPI_VER_CURRENT )
00221         test_fail( __FILE__, __LINE__, "PAPI_library_init", retval );
00222     if ( ( retval = PAPI_set_debug( PAPI_VERB_ECONT ) ) != PAPI_OK )
00223         test_fail( __FILE__, __LINE__, "PAPI_set_debug", retval );
00224     if ( ( retval = PAPI_query_event( PAPI_TOT_CYC ) ) != PAPI_OK )
00225         test_fail( __FILE__, __LINE__, "PAPI_query_event", retval );
00226     if ( ( retval = PAPI_query_event( PAPI_TOT_INS ) ) != PAPI_OK )
00227         test_fail( __FILE__, __LINE__, "PAPI_query_event", retval );
00228     if ( ( retval = PAPI_create_eventset( &EventSet ) ) != PAPI_OK )
00229         test_fail( __FILE__, __LINE__, "PAPI_create_eventset", retval );
00230 
00231     if ( ( retval = PAPI_add_event( EventSet, PAPI_TOT_CYC ) ) != PAPI_OK )
00232         test_fail( __FILE__, __LINE__, "PAPI_add_event", retval );
00233 
00234     if ( ( retval = PAPI_add_event( EventSet, PAPI_TOT_INS ) ) != PAPI_OK )
00235         if ( ( retval = PAPI_add_event( EventSet, PAPI_TOT_IIS ) ) != PAPI_OK )
00236             test_fail( __FILE__, __LINE__, "PAPI_add_event", retval );
00237 
00238     /* Make sure no errors and warm up */
00239 
00240     totcyc = PAPI_get_real_cyc(  );
00241     if ( ( retval = PAPI_start( EventSet ) ) != PAPI_OK )
00242         test_fail( __FILE__, __LINE__, "PAPI_start", retval );
00243     if ( ( retval = PAPI_stop( EventSet, NULL ) ) != PAPI_OK )
00244         test_fail( __FILE__, __LINE__, "PAPI_stop", retval );
00245 
00246     array =
00247         ( long long * ) malloc( ( size_t ) num_iters * sizeof ( long long ) );
00248     if ( array == NULL )
00249         test_fail( __FILE__, __LINE__, "PAPI_stop", retval );
00250 
00251     /* Determine clock latency */
00252 
00253     printf( "\nPerforming loop latency test...\n" );
00254 
00255     for ( i = 0; i < num_iters; i++ ) {
00256         totcyc = PAPI_get_real_cyc(  );
00257         totcyc = PAPI_get_real_cyc(  ) - totcyc;
00258         array[i] = totcyc;
00259     }
00260 
00261     do_output( 0, array, bins, show_std_dev, show_dist );
00262 
00263     /* Start the start/stop eval */
00264 
00265     printf( "\nPerforming start/stop test...\n" );
00266 
00267     for ( i = 0; i < num_iters; i++ ) {
00268         totcyc = PAPI_get_real_cyc(  );
00269         retval_start=PAPI_start( EventSet );
00270         retval_stop=PAPI_stop( EventSet, values );
00271         totcyc = PAPI_get_real_cyc(  ) - totcyc;        
00272         array[i] = totcyc;
00273         if (retval_start || retval_stop) {
00274            test_fail( __FILE__, __LINE__, "PAPI start/stop", retval_start );
00275         }
00276     }
00277 
00278     do_output( 1, array, bins, show_std_dev, show_dist );
00279 
00280     /* Start the read eval */
00281     printf( "\nPerforming read test...\n" );
00282 
00283     if ( ( retval = PAPI_start( EventSet ) ) != PAPI_OK )
00284         test_fail( __FILE__, __LINE__, "PAPI_start", retval );
00285     PAPI_read( EventSet, values );
00286 
00287     for ( i = 0; i < num_iters; i++ ) {
00288         totcyc = PAPI_get_real_cyc(  );
00289         PAPI_read( EventSet, values );
00290         totcyc = PAPI_get_real_cyc(  ) - totcyc;
00291         array[i] = totcyc;
00292     }
00293     if ( ( retval = PAPI_stop( EventSet, values ) ) != PAPI_OK )
00294         test_fail( __FILE__, __LINE__, "PAPI_stop", retval );
00295 
00296     do_output( 2, array, bins, show_std_dev, show_dist );
00297 
00298     /* Start the read with timestamp eval */
00299     printf( "\nPerforming read with timestamp test...\n" );
00300 
00301     if ( ( retval = PAPI_start( EventSet ) ) != PAPI_OK )
00302         test_fail( __FILE__, __LINE__, "PAPI_start", retval );
00303     PAPI_read_ts( EventSet, values, &totcyc );
00304 
00305     for ( i = 0; i < num_iters; i++ ) {
00306         PAPI_read_ts( EventSet, values, &array[i] );
00307     }
00308     if ( ( retval = PAPI_stop( EventSet, values ) ) != PAPI_OK )
00309         test_fail( __FILE__, __LINE__, "PAPI_stop", retval );
00310 
00311     /* post-process the timing array */
00312     for ( i = num_iters - 1; i > 0; i-- ) {
00313         array[i] -= array[i - 1];
00314     }
00315     array[0] -= totcyc;
00316 
00317     do_output( 3, array, bins, show_std_dev, show_dist );
00318 
00319     /* Start the accum eval */
00320     printf( "\nPerforming accum test...\n" );
00321 
00322     if ( ( retval = PAPI_start( EventSet ) ) != PAPI_OK )
00323         test_fail( __FILE__, __LINE__, "PAPI_start", retval );
00324     PAPI_accum( EventSet, values );
00325 
00326     for ( i = 0; i < num_iters; i++ ) {
00327         totcyc = PAPI_get_real_cyc(  );
00328         PAPI_accum( EventSet, values );
00329         totcyc = PAPI_get_real_cyc(  ) - totcyc;
00330         array[i] = totcyc;
00331     }
00332     if ( ( retval = PAPI_stop( EventSet, values ) ) != PAPI_OK )
00333         test_fail( __FILE__, __LINE__, "PAPI_stop", retval );
00334 
00335     do_output( 4, array, bins, show_std_dev, show_dist );
00336 
00337     /* Start the reset eval */
00338     printf( "\nPerforming reset test...\n" );
00339 
00340     if ( ( retval = PAPI_start( EventSet ) ) != PAPI_OK )
00341         test_fail( __FILE__, __LINE__, "PAPI_start", retval );
00342 
00343     for ( i = 0; i < num_iters; i++ ) {
00344         totcyc = PAPI_get_real_cyc(  );
00345         PAPI_reset( EventSet );
00346         totcyc = PAPI_get_real_cyc(  ) - totcyc;
00347         array[i] = totcyc;
00348     }
00349     if ( ( retval = PAPI_stop( EventSet, values ) ) != PAPI_OK )
00350         test_fail( __FILE__, __LINE__, "PAPI_stop", retval );
00351 
00352     do_output( 5, array, bins, show_std_dev, show_dist );
00353 
00354     /* Derived event test */
00355     PAPI_cleanup_eventset( EventSet );
00356 
00357     event = 0 | PAPI_PRESET_MASK;
00358 
00359     if ( ( event = find_derived_postfix( event ) ) != PAPI_NULL ) {
00360       if ( (retval = PAPI_add_event( EventSet, event) ) != PAPI_OK )
00361         test_fail(__FILE__, __LINE__, "PAPI_add_event", retval);
00362 
00363       PAPI_get_event_info(event, &info);
00364       printf( "\nPerforming DERIVED_POSTFIX PAPI_read(%d counters)  test...", info.count );
00365 
00366       if ( ( retval = PAPI_start( EventSet ) ) != PAPI_OK )
00367         test_fail( __FILE__, __LINE__, "PAPI_start", retval );
00368       PAPI_read( EventSet, values );
00369 
00370       for ( i = 0; i < num_iters; i++ ) {
00371         totcyc = PAPI_get_real_cyc(  );
00372         PAPI_read( EventSet, values );
00373         totcyc = PAPI_get_real_cyc(  ) - totcyc;
00374         array[i] = totcyc;
00375       }
00376       if ( ( retval = PAPI_stop( EventSet, values ) ) != PAPI_OK )
00377         test_fail( __FILE__, __LINE__, "PAPI_stop", retval );
00378 
00379       do_output( 6, array, bins, show_std_dev, show_dist );
00380 
00381     } else {
00382       printf("\tI was unable to find a DERIVED_POSTFIX preset event to "
00383           "test on this architecture, skipping.\n");
00384     }
00385 
00386     if ( ( event = find_derived_add( event ) ) != PAPI_NULL ) {
00387       if ( (retval = PAPI_add_event( EventSet, event) ) != PAPI_OK )
00388         test_fail(__FILE__, __LINE__, "PAPI_add_event", retval);
00389 
00390       PAPI_get_event_info(event, &info);
00391       printf( "\nPerforming DERIVED_[ADD|SUB] PAPI_read(%d counters)  test...", info.count );
00392 
00393       if ( ( retval = PAPI_start( EventSet ) ) != PAPI_OK )
00394         test_fail( __FILE__, __LINE__, "PAPI_start", retval );
00395       PAPI_read( EventSet, values );
00396 
00397       for ( i = 0; i < num_iters; i++ ) {
00398         totcyc = PAPI_get_real_cyc(  );
00399         PAPI_read( EventSet, values );
00400         totcyc = PAPI_get_real_cyc(  ) - totcyc;
00401         array[i] = totcyc;
00402       }
00403       if ( ( retval = PAPI_stop( EventSet, values ) ) != PAPI_OK )
00404         test_fail( __FILE__, __LINE__, "PAPI_stop", retval );
00405 
00406       do_output( 7, array, bins, show_std_dev, show_dist );
00407     } else {
00408       printf("\tI was unable to find a suitable DERIVED_[ADD|SUB] event to test, skipping.\n");
00409     }
00410 
00411     free( array );
00412     test_pass( __FILE__, NULL, 0 );
00413     exit( 1 );
00414 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines