|
PAPI
5.0.1.0
|
00001 /* This program shows how to use PAPI_sprofil */ 00002 00003 #include <stdlib.h> 00004 #include <stdio.h> 00005 #include <unistd.h> 00006 #include <sys/types.h> 00007 #include <sys/stat.h> 00008 #include <fcntl.h> 00009 #include <string.h> 00010 00011 #include "papi.h" /* This needs to be included every time you use PAPI */ 00012 00013 #define NUM_FLOPS 20000000 00014 #define NUM_ITERS 100000 00015 #define THRESHOLD 100000 00016 #define ERROR_RETURN(retval) { fprintf(stderr, "Error %d %s:line %d: \n", retval,__FILE__,__LINE__); exit(retval); } 00017 00018 #if (defined(linux) && defined(__ia64__)) || (defined(_AIX)) 00019 #define DO_FLOPS1 (caddr_t)(*(void **)do_flops1) 00020 #define DO_FLOPS2 (caddr_t)(*(void **)do_flops2) 00021 #else 00022 #define DO_FLOPS1 (caddr_t)(do_flops1) 00023 #define DO_FLOPS2 (caddr_t)(do_flops2) 00024 #endif 00025 00026 void do_flops2(int); 00027 volatile double t1 = 0.8, t2 = 0.9; 00028 void do_flops1(int n) 00029 { 00030 int i; 00031 double c = 22222.11; 00032 00033 for (i = 0; i < n; i++) 00034 c -= t1 * t2; 00035 } 00036 00037 void do_both(int n) 00038 { 00039 int i; 00040 const int flops2 = NUM_FLOPS / n; 00041 const int flops1 = NUM_FLOPS / n; 00042 00043 for (i = 0; i < n; i++) 00044 { 00045 do_flops1(flops1); 00046 do_flops2(flops2); 00047 } 00048 } 00049 00050 int main(int argc, char **argv) 00051 { 00052 int i , PAPI_event; 00053 int EventSet = PAPI_NULL; 00054 unsigned short *profbuf; 00055 unsigned short *profbuf2; 00056 unsigned short *profbuf3; 00057 unsigned long length; 00058 caddr_t start, end; 00059 long long values[2]; 00060 const PAPI_exe_info_t *prginfo = NULL; 00061 PAPI_sprofil_t sprof[3]; 00062 int retval; 00063 00064 /* initializaion */ 00065 if ((retval = PAPI_library_init(PAPI_VER_CURRENT)) != PAPI_VER_CURRENT) 00066 { 00067 printf("Library initialization error! \n"); 00068 exit(1); 00069 } 00070 00071 if ((prginfo = PAPI_get_executable_info()) == NULL) 00072 ERROR_RETURN(1); 00073 00074 start = prginfo->address_info.text_start; 00075 end = prginfo->address_info.text_end; 00076 length = (end - start)/sizeof(unsigned short) * sizeof(unsigned short); 00077 printf("start= %p end =%p \n", start, end); 00078 00079 profbuf = (unsigned short *) malloc(length); 00080 if (profbuf == NULL) 00081 ERROR_RETURN(PAPI_ESYS); 00082 00083 memset(profbuf, 0x00, length ); 00084 00085 profbuf2 = (unsigned short *) malloc(length); 00086 if (profbuf2 == NULL) 00087 ERROR_RETURN(PAPI_ESYS); 00088 00089 memset(profbuf2, 0x00, length ); 00090 00091 profbuf3 = (unsigned short *) malloc(1 * sizeof(unsigned short)); 00092 if (profbuf3 == NULL) 00093 ERROR_RETURN(PAPI_ESYS); 00094 00095 memset(profbuf3, 0x00, 1 * sizeof(unsigned short)); 00096 00097 /* First half */ 00098 sprof[0].pr_base = profbuf; 00099 sprof[0].pr_size = length / 2; 00100 sprof[0].pr_off = DO_FLOPS2; 00101 fprintf(stderr, "do_flops is at %p %lx\n", &do_flops2, strtoul(sprof[0].pr_off,NULL,0)); 00102 00103 sprof[0].pr_scale = 65536; /* constant needed by PAPI_sprofil */ 00104 /* Second half */ 00105 sprof[1].pr_base = profbuf2; 00106 sprof[1].pr_size = length / 2; 00107 sprof[1].pr_off = DO_FLOPS1; 00108 fprintf(stderr, "do_flops1 is at %p %lx\n", &do_flops1, strtoul(sprof[1].pr_off,NULL,0)); 00109 sprof[1].pr_scale = 65536; /* constant needed by PAPI_sprofil */ 00110 00111 /* Overflow bin */ 00112 sprof[2].pr_base = profbuf3; 00113 sprof[2].pr_size = 1; 00114 sprof[2].pr_off = 0; 00115 sprof[2].pr_scale = 0x2; /* constant needed by PAPI_sprofil */ 00116 00117 /* Creating the eventset */ 00118 if ( (retval = PAPI_create_eventset(&EventSet)) != PAPI_OK) 00119 ERROR_RETURN(retval); 00120 00121 PAPI_event = PAPI_TOT_CYC; 00122 /* Add Total Instructions Executed to our EventSet */ 00123 if ( (retval = PAPI_add_event(EventSet, PAPI_event)) != PAPI_OK) 00124 ERROR_RETURN(retval); 00125 00126 /* Add Total Instructions Executed to our EventSet */ 00127 if ( (retval = PAPI_add_event(EventSet, PAPI_TOT_INS)) != PAPI_OK) 00128 ERROR_RETURN(retval); 00129 00130 /* set profile flag */ 00131 if ((retval = PAPI_sprofil(sprof, 3, EventSet, PAPI_event, THRESHOLD, 00132 PAPI_PROFIL_POSIX)) != PAPI_OK) 00133 ERROR_RETURN(retval); 00134 00135 if ((retval = PAPI_start(EventSet)) != PAPI_OK) 00136 ERROR_RETURN(retval); 00137 00138 do_both(NUM_ITERS); 00139 00140 if ((retval = PAPI_stop(EventSet, values)) != PAPI_OK) 00141 ERROR_RETURN(retval); 00142 00143 /* to clear the profile flag before removing the events */ 00144 if ((retval = PAPI_sprofil(sprof, 3, EventSet, PAPI_event, 0, 00145 PAPI_PROFIL_POSIX)) != PAPI_OK) 00146 ERROR_RETURN(retval); 00147 00148 /* free the resources hold by PAPI */ 00149 PAPI_shutdown(); 00150 00151 printf("Test case: PAPI_sprofil()\n"); 00152 printf("---------Buffer 1--------\n"); 00153 for (i = 0; i < length / 2; i++) 00154 { 00155 if (profbuf[i]) 00156 printf("0x%lx\t%d\n", strtoul(DO_FLOPS2,NULL,0) + 2 * i, profbuf[i]); 00157 } 00158 printf("---------Buffer 2--------\n"); 00159 for (i = 0; i < length / 2; i++) 00160 { 00161 if (profbuf2[i]) 00162 printf("0x%lx\t%d\n", strtoul(DO_FLOPS1,NULL,0) + 2 * i, profbuf2[i]); 00163 } 00164 printf("-------------------------\n"); 00165 printf("%u samples fell outside the regions.\n", *profbuf3); 00166 00167 exit(0); 00168 } 00169 00170 /* Declare a and b to be volatile. 00171 This is to try to keep the 00172 compiler from optimizing the loop */ 00173 volatile double a = 0.5, b = 2.2; 00174 void do_flops2(int n) 00175 { 00176 int i; 00177 double c = 0.11; 00178 00179 for (i = 0; i < n; i++) 00180 c += a * b; 00181 } 00182