|
PAPI
5.0.1.0
|
00001 /* This file performs the following test: start, stop and timer 00002 functionality for 2 slave pthreads 00003 00004 - It attempts to use the following two counters. It may use less 00005 depending on hardware counter resource limitations. These are counted 00006 in the default counting domain and default granularity, depending on 00007 the platform. Usually this is the user domain (PAPI_DOM_USER) and 00008 thread context (PAPI_GRN_THR). 00009 00010 + PAPI_FP_INS 00011 + PAPI_TOT_CYC 00012 00013 Each of 2 slave pthreads: 00014 - Get cyc. 00015 - Get us. 00016 - Start counters 00017 - Do flops 00018 - Stop and read counters 00019 - Get us. 00020 - Get cyc. 00021 00022 Master pthread: 00023 - Get us. 00024 - Get cyc. 00025 - Fork threads 00026 - Wait for threads to exit 00027 - Get us. 00028 - Get cyc. 00029 */ 00030 00031 #include <pthread.h> 00032 00033 #include "papi_test.h" 00034 00035 void * 00036 Thread( void *arg ) 00037 { 00038 int retval, num_tests = 1; 00039 int EventSet1 = PAPI_NULL; 00040 int PAPI_event, mask1; 00041 int num_events1; 00042 long long **values; 00043 long long elapsed_us, elapsed_cyc; 00044 char event_name[PAPI_MAX_STR_LEN]; 00045 00046 retval = PAPI_register_thread( ); 00047 if ( retval != PAPI_OK ) { 00048 test_fail( __FILE__, __LINE__, "PAPI_register_thread", retval ); 00049 } 00050 00051 printf( "Thread 0x%x started\n", ( int ) pthread_self( ) ); 00052 00053 /* add PAPI_TOT_CYC and one of the events in 00054 PAPI_FP_INS, PAPI_FP_OPS or PAPI_TOT_INS, 00055 depending on the availability of the event 00056 on the platform */ 00057 EventSet1 = add_two_events( &num_events1, &PAPI_event, &mask1 ); 00058 00059 retval = PAPI_event_code_to_name( PAPI_event, event_name ); 00060 if ( retval != PAPI_OK ) { 00061 test_fail( __FILE__, __LINE__, "PAPI_event_code_to_name", retval ); 00062 } 00063 00064 values = allocate_test_space( num_tests, num_events1 ); 00065 00066 elapsed_us = PAPI_get_real_usec( ); 00067 elapsed_cyc = PAPI_get_real_cyc( ); 00068 00069 retval = PAPI_start( EventSet1 ); 00070 if ( retval != PAPI_OK ) { 00071 test_fail( __FILE__, __LINE__, "PAPI_start", retval ); 00072 } 00073 00074 do_flops( *( int * ) arg ); 00075 00076 retval = PAPI_stop( EventSet1, values[0] ); 00077 if ( retval != PAPI_OK ) { 00078 test_fail( __FILE__, __LINE__, "PAPI_stop", retval ); 00079 } 00080 00081 elapsed_us = PAPI_get_real_usec( ) - elapsed_us; 00082 elapsed_cyc = PAPI_get_real_cyc( ) - elapsed_cyc; 00083 00084 remove_test_events( &EventSet1, mask1 ); 00085 00086 if ( !TESTS_QUIET ) { 00087 printf( "Thread 0x%x %-12s : \t%lld\n", ( int ) pthread_self( ), 00088 event_name, values[0][1] ); 00089 printf( "Thread 0x%x PAPI_TOT_CYC : \t%lld\n", (int) pthread_self(), 00090 values[0][0] ); 00091 printf( "Thread 0x%x Real usec : \t%lld\n", 00092 ( int ) pthread_self( ), 00093 elapsed_us ); 00094 printf( "Thread 0x%x Real cycles : \t%lld\n", (int) pthread_self(), 00095 elapsed_cyc ); 00096 } 00097 00098 free_test_space( values, num_tests ); 00099 00100 retval = PAPI_unregister_thread( ); 00101 if ( retval != PAPI_OK ) 00102 test_fail( __FILE__, __LINE__, "PAPI_unregister_thread", retval ); 00103 return NULL; 00104 } 00105 00106 int 00107 main( int argc, char **argv ) 00108 { 00109 pthread_t e_th, f_th, g_th, h_th; 00110 int flops1, flops2, flops3, flops4; 00111 int retval, rc; 00112 pthread_attr_t attr; 00113 long long elapsed_us, elapsed_cyc; 00114 00115 /* Set TESTS_QUIET variable */ 00116 tests_quiet( argc, argv ); 00117 00118 /* Init PAPI library */ 00119 retval = PAPI_library_init( PAPI_VER_CURRENT ); 00120 if ( retval != PAPI_VER_CURRENT ) { 00121 test_fail( __FILE__, __LINE__, "PAPI_library_init", retval ); 00122 } 00123 00124 retval = PAPI_thread_init( ( unsigned long ( * )( void ) ) 00125 ( pthread_self ) ); 00126 if ( retval != PAPI_OK ) { 00127 if ( retval == PAPI_ECMP ) { 00128 test_skip( __FILE__, __LINE__, "PAPI_thread_init", retval ); 00129 } 00130 else { 00131 test_fail( __FILE__, __LINE__, "PAPI_thread_init", retval ); 00132 } 00133 } 00134 00135 elapsed_us = PAPI_get_real_usec( ); 00136 00137 elapsed_cyc = PAPI_get_real_cyc( ); 00138 00139 pthread_attr_init( &attr ); 00140 #ifdef PTHREAD_CREATE_UNDETACHED 00141 pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_UNDETACHED ); 00142 #endif 00143 #ifdef PTHREAD_SCOPE_SYSTEM 00144 retval = pthread_attr_setscope( &attr, PTHREAD_SCOPE_SYSTEM ); 00145 if ( retval != 0 ) 00146 test_skip( __FILE__, __LINE__, "pthread_attr_setscope", retval ); 00147 #endif 00148 00149 flops1 = 1000000; 00150 rc = pthread_create( &e_th, &attr, Thread, ( void * ) &flops1 ); 00151 if ( rc ) { 00152 retval = PAPI_ESYS; 00153 test_fail( __FILE__, __LINE__, "pthread_create", retval ); 00154 } 00155 flops2 = 2000000; 00156 rc = pthread_create( &f_th, &attr, Thread, ( void * ) &flops2 ); 00157 if ( rc ) { 00158 retval = PAPI_ESYS; 00159 test_fail( __FILE__, __LINE__, "pthread_create", retval ); 00160 } 00161 00162 flops3 = 4000000; 00163 rc = pthread_create( &g_th, &attr, Thread, ( void * ) &flops3 ); 00164 if ( rc ) { 00165 retval = PAPI_ESYS; 00166 test_fail( __FILE__, __LINE__, "pthread_create", retval ); 00167 } 00168 00169 flops4 = 8000000; 00170 rc = pthread_create( &h_th, &attr, Thread, ( void * ) &flops4 ); 00171 if ( rc ) { 00172 retval = PAPI_ESYS; 00173 test_fail( __FILE__, __LINE__, "pthread_create", retval ); 00174 } 00175 00176 pthread_attr_destroy( &attr ); 00177 flops1 = 500000; 00178 Thread( &flops1 ); 00179 pthread_join( h_th, NULL ); 00180 pthread_join( g_th, NULL ); 00181 pthread_join( f_th, NULL ); 00182 pthread_join( e_th, NULL ); 00183 00184 elapsed_cyc = PAPI_get_real_cyc( ) - elapsed_cyc; 00185 elapsed_us = PAPI_get_real_usec( ) - elapsed_us; 00186 00187 if ( !TESTS_QUIET ) { 00188 printf( "Master real usec : \t%lld\n", elapsed_us ); 00189 printf( "Master real cycles : \t%lld\n", elapsed_cyc ); 00190 } 00191 00192 test_pass( __FILE__, NULL, 0 ); 00193 pthread_exit( NULL ); 00194 exit( 1 ); 00195 }