PAPI  5.0.1.0
overflow_pthreads.c
Go to the documentation of this file.
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 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines