|
PAPI
5.0.1.0
|
00001 /* This file performs the following test: overflow dispatch with pthreads 00002 00003 - This example tests the dispatch of overflow calls from PAPI. The event 00004 set is counted in the default counting domain and default granularity, 00005 depending on the platform. Usually this is the user domain 00006 (PAPI_DOM_USER) and thread context (PAPI_GRN_THR). 00007 00008 The Eventset contains: 00009 + PAPI_TOT_INS (overflow monitor) 00010 + PAPI_TOT_CYC 00011 00012 Each thread will do the followings : 00013 - enable overflow 00014 - Start eventset 1 00015 - Do flops 00016 - Stop eventset 1 00017 - disable overflow 00018 */ 00019 #include <stdio.h> 00020 #include <stdlib.h> 00021 #include <pthread.h> 00022 #include "papi.h" 00023 00024 #define THRESHOLD 200000 00025 #define OVER_FMT "handler(%d ) Overflow at %p! bit=0x%llx \n" 00026 #define ERROR_RETURN(retval) { fprintf(stderr, "Error %d %s:line %d: \n", retval,__FILE__,__LINE__); exit(retval); } 00027 00028 00029 int total = 0; 00030 00031 void do_flops(int n) 00032 { 00033 int i; 00034 double c = 0.11; 00035 double a = 0.5; 00036 double b = 6.2; 00037 00038 for (i=0; i < n; i++) 00039 c += a * b; 00040 } 00041 00042 /* overflow handler */ 00043 void 00044 handler(int EventSet, void *address, long long overflow_vector, void *context) 00045 { 00046 fprintf(stderr, OVER_FMT, EventSet, address, overflow_vector); 00047 total++; 00048 } 00049 00050 void *Thread(void *arg) 00051 { 00052 int retval; 00053 int EventSet1=PAPI_NULL; 00054 long long values[2]; 00055 long long elapsed_us, elapsed_cyc; 00056 00057 fprintf(stderr,"Thread %lx running PAPI\n",PAPI_thread_id()); 00058 00059 /* create the event set */ 00060 if ( (retval = PAPI_create_eventset(&EventSet1))!=PAPI_OK) 00061 ERROR_RETURN(retval); 00062 00063 /* query whether the event exists */ 00064 if ((retval=PAPI_query_event(PAPI_TOT_INS)) != PAPI_OK) 00065 ERROR_RETURN(retval); 00066 if ((retval=PAPI_query_event(PAPI_TOT_CYC)) != PAPI_OK) 00067 ERROR_RETURN(retval); 00068 00069 /* add events to the event set */ 00070 if ( (retval = PAPI_add_event(EventSet1, PAPI_TOT_INS))!= PAPI_OK) 00071 ERROR_RETURN(retval); 00072 00073 if ( (retval = PAPI_add_event(EventSet1, PAPI_TOT_CYC)) != PAPI_OK) 00074 ERROR_RETURN(retval); 00075 00076 elapsed_us = PAPI_get_real_usec(); 00077 00078 elapsed_cyc = PAPI_get_real_cyc(); 00079 00080 retval = PAPI_overflow(EventSet1, PAPI_TOT_CYC, THRESHOLD, 0, handler); 00081 if(retval !=PAPI_OK) 00082 ERROR_RETURN(retval); 00083 00084 /* start counting */ 00085 if((retval = PAPI_start(EventSet1))!=PAPI_OK) 00086 ERROR_RETURN(retval); 00087 00088 do_flops(*(int *)arg); 00089 00090 if ((retval = PAPI_stop(EventSet1, values))!=PAPI_OK) 00091 ERROR_RETURN(retval); 00092 00093 elapsed_us = PAPI_get_real_usec() - elapsed_us; 00094 00095 elapsed_cyc = PAPI_get_real_cyc() - elapsed_cyc; 00096 00097 /* disable overflowing */ 00098 retval = PAPI_overflow(EventSet1, PAPI_TOT_CYC, 0, 0, handler); 00099 if(retval !=PAPI_OK) 00100 ERROR_RETURN(retval); 00101 00102 /* remove the event from the eventset */ 00103 retval = PAPI_remove_event(EventSet1, PAPI_TOT_INS); 00104 if (retval != PAPI_OK) 00105 ERROR_RETURN(retval); 00106 00107 retval = PAPI_remove_event(EventSet1, PAPI_TOT_CYC); 00108 if (retval != PAPI_OK) 00109 ERROR_RETURN(retval); 00110 00111 printf("Thread 0x%x PAPI_TOT_INS : \t%lld\n",(int)PAPI_thread_id(), 00112 values[0]); 00113 printf(" PAPI_TOT_CYC: \t%lld\n", values[1]); 00114 printf(" Real usec : \t%lld\n", elapsed_us); 00115 printf(" Real cycles : \t%lld\n", elapsed_cyc); 00116 00117 pthread_exit(NULL); 00118 } 00119 00120 int main(int argc, char **argv) 00121 { 00122 pthread_t thread_one; 00123 pthread_t thread_two; 00124 int flops1, flops2; 00125 int rc,retval; 00126 pthread_attr_t attr; 00127 long long elapsed_us, elapsed_cyc; 00128 00129 00130 /* papi library initialization */ 00131 if ((retval=PAPI_library_init(PAPI_VER_CURRENT)) != PAPI_VER_CURRENT) 00132 { 00133 printf("Library initialization error! \n"); 00134 exit(1); 00135 } 00136 00137 /* thread initialization */ 00138 retval=PAPI_thread_init((unsigned long(*)(void))(pthread_self)); 00139 if (retval != PAPI_OK) 00140 ERROR_RETURN(retval); 00141 00142 /* return the number of microseconds since some arbitrary starting point */ 00143 elapsed_us = PAPI_get_real_usec(); 00144 00145 /* return the number of cycles since some arbitrary starting point */ 00146 elapsed_cyc = PAPI_get_real_cyc(); 00147 00148 /* pthread attribution init */ 00149 pthread_attr_init(&attr); 00150 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM); 00151 00152 /* create the first thread */ 00153 flops1 = 1000000; 00154 rc = pthread_create(&thread_one, &attr, Thread, (void *)&flops1); 00155 if (rc) 00156 ERROR_RETURN(rc); 00157 00158 /* create the second thread */ 00159 flops2 = 4000000; 00160 rc = pthread_create(&thread_two, &attr, Thread, (void *)&flops2); 00161 if (rc) 00162 ERROR_RETURN(rc); 00163 00164 /* wait for the threads to finish */ 00165 pthread_attr_destroy(&attr); 00166 pthread_join(thread_one, NULL); 00167 pthread_join(thread_two, NULL); 00168 00169 /* compute the elapsed cycles and microseconds */ 00170 elapsed_cyc = PAPI_get_real_cyc() - elapsed_cyc; 00171 00172 elapsed_us = PAPI_get_real_usec() - elapsed_us; 00173 00174 printf("Master real usec : \t%lld\n", elapsed_us); 00175 printf("Master real cycles : \t%lld\n", elapsed_cyc); 00176 00177 /* clean up */ 00178 PAPI_shutdown(); 00179 exit(0); 00180 } 00181