PAPI  5.7.0.0
papi_br_prc.c
Go to the documentation of this file.
1 /* This file attempts to test the predicted correctly branches */
2 /* performance event as counted by PAPI_BR_PRC */
3 
4 /* Ideally this event should measure */
5 /* predicted correctly *conditional* branches */
6 
7 /* If that's not available, then use total branches. */
8 
9 /* by Vince Weaver, <vincent.weaver@maine.edu> */
10 
11 
12 #include <stdlib.h>
13 #include <stdio.h>
14 #include <unistd.h>
15 #include <string.h>
16 
17 #include "papi.h"
18 #include "papi_test.h"
19 
20 #include "display_error.h"
21 #include "testcode.h"
22 
23 
24 
25 int main(int argc, char **argv) {
26 
27  int num_runs=100,i;
28  int num_random_branches=500000;
29  long long high=0,low=0,average=0,expected=1500000;
30  long long expected_high,expected_low;
31 
32  long long count,total=0;
33  int quiet=0,retval,ins_result;
34  int total_eventset=PAPI_NULL,miss_eventset=PAPI_NULL;
35 
36  quiet=tests_quiet(argc,argv);
37 
38  if (!quiet) {
39  printf("\nTesting the PAPI_BR_PRC event.\n\n");
40  printf("This should measure predicted correctly conditional branches\n");
41  printf("If such a counter is not available, it may report predicted correctly\n");
42  printf("total branches instead.\n");
43  }
44 
45  /* Init the PAPI library */
47  if ( retval != PAPI_VER_CURRENT ) {
48  test_fail( __FILE__, __LINE__, "PAPI_library_init", retval );
49  }
50 
51  /* Create total eventset */
52  retval=PAPI_create_eventset(&total_eventset);
53  if (retval!=PAPI_OK) {
54  test_fail( __FILE__, __LINE__, "PAPI_create_eventset", retval );
55  }
56 
57  retval=PAPI_add_named_event(total_eventset,"PAPI_BR_CN");
58  if (retval!=PAPI_OK) {
59  if (!quiet) printf("Could not add PAPI_BR_CN\n");
60  //test_skip( __FILE__, __LINE__, "adding PAPI_BR_CN", retval );
61 
62  retval=PAPI_add_named_event(total_eventset,"PAPI_BR_INS");
63  if (retval!=PAPI_OK) {
64  if (!quiet) printf("Could not add PAPI_BR_INS\n");
65  test_skip( __FILE__, __LINE__, "adding PAPI_BR_INS", retval );
66  }
67  }
68 
69 
70 
71 
72 
73  /* Create correct eventset */
74  retval=PAPI_create_eventset(&miss_eventset);
75  if (retval!=PAPI_OK) {
76  test_fail( __FILE__, __LINE__, "PAPI_create_eventset", retval );
77  }
78 
79  retval=PAPI_add_named_event(miss_eventset,"PAPI_BR_PRC");
80  if (retval!=PAPI_OK) {
81  if (!quiet) printf("Could not add PAPI_BR_PRC\n");
82  test_skip( __FILE__, __LINE__, "adding PAPI_BR_PRC", retval );
83  }
84 
85  if (!quiet) {
86  printf("\nPart 1: Testing that easy to predict loop has few misses\n");
87  printf("Testing a loop with %lld branches (%d times):\n",
88  expected,num_runs);
89  printf("\tOn a simple loop like this, "
90  "hit rate should be very high.\n");
91  }
92 
93  for(i=0;i<num_runs;i++) {
94 
95  PAPI_reset(miss_eventset);
96  PAPI_start(miss_eventset);
97 
98  ins_result=branches_testcode();
99 
100  retval=PAPI_stop(miss_eventset,&count);
101 
102  if (ins_result==CODE_UNIMPLEMENTED) {
103  fprintf(stderr,"\tCode unimplemented\n");
104  test_skip( __FILE__, __LINE__, "unimplemented", 0);
105  }
106 
107  if (retval!=PAPI_OK) {
108  test_fail( __FILE__, __LINE__,
109  "reading PAPI_TOT_INS", retval );
110  }
111 
112  if (count>high) high=count;
113  if ((low==0) || (count<low)) low=count;
114  total+=count;
115  }
116 
117  average=(total/num_runs);
118 
119  if (!quiet) printf("\tAverage number of branch hits: %lld\n",average);
120 
121  if (average<expected/2) {
122  if (!quiet) printf("Branch miss rate too high\n");
123  test_fail( __FILE__, __LINE__, "Error too high", 1 );
124  }
125 
126  /*******************/
127 
128  if (!quiet) {
129  printf("\nPart 2\n");
130  }
131 
132  high=0; low=0; total=0;
133 
134  for(i=0;i<num_runs;i++) {
135  PAPI_reset(total_eventset);
136  PAPI_start(total_eventset);
137 
138  ins_result=random_branches_testcode(num_random_branches,1);
139 
140  retval=PAPI_stop(total_eventset,&count);
141 
142  if (ins_result==CODE_UNIMPLEMENTED) {
143  fprintf(stderr,"\tCode unimplemented\n");
144  test_skip( __FILE__, __LINE__, "unimplemented", 0);
145  }
146 
147  if (retval!=PAPI_OK) {
148  test_fail( __FILE__, __LINE__,
149  "reading PAPI_TOT_INS", retval );
150  }
151 
152  if (count>high) high=count;
153  if ((low==0) || (count<low)) low=count;
154  total+=count;
155  }
156 
157  average=total/num_runs;
158 
159  expected=average;
160  if (!quiet) {
161  printf("\nTesting a function that branches "
162  "based on a random number\n");
163  printf(" The loop has %lld conditional branches.\n",expected);
164  printf(" %d are random branches.\n",num_random_branches);
165  }
166 
167  high=0; low=0; total=0;
168 
169  for(i=0;i<num_runs;i++) {
170  PAPI_reset(miss_eventset);
171  PAPI_start(miss_eventset);
172 
173  ins_result=random_branches_testcode(num_random_branches,1);
174 
175  retval=PAPI_stop(miss_eventset,&count);
176 
177  if (ins_result==CODE_UNIMPLEMENTED) {
178  fprintf(stderr,"\tCode unimplemented\n");
179  test_skip( __FILE__, __LINE__, "unimplemented", 0);
180  }
181 
182  if (retval!=PAPI_OK) {
183  test_fail( __FILE__, __LINE__,
184  "reading eventset", retval );
185  }
186 
187  if (count>high) high=count;
188  if ((low==0) || (count<low)) low=count;
189  total+=count;
190  }
191 
192  average=total/num_runs;
193 
194  expected_low=expected-((num_random_branches/4)*3);
195  expected_high=expected-(num_random_branches/4);
196 
197  if (!quiet) {
198  printf("\nOut of %lld branches, "
199  "%lld were correctly predicted\n",expected,average);
200  printf("Assuming a good random number generator and no "
201  "freaky luck\n");
202  printf("The mispredicts should be roughly "
203  "between %lld and %lld\n",
204  expected_low,expected_high);
205 
206  }
207 
208  if ( average < expected_low) {
209  if (!quiet) printf("Branch hits too low\n");
210  test_fail( __FILE__, __LINE__, "Error too low", 1 );
211  }
212 
213  if (average > expected_high) {
214  if (!quiet) printf("Branch hits too high\n");
215  test_fail( __FILE__, __LINE__, "Error too high", 1 );
216  }
217 
218  if (!quiet) printf("\n");
219 
220  test_pass( __FILE__ );
221 
222  PAPI_shutdown();
223 
224  return 0;
225 
226 }
#define PAPI_OK
Definition: fpapi.h:105
int PAPI_stop(int EventSet, long long *values)
Definition: papi.c:2314
int random_branches_testcode(int number, int quiet)
void test_pass(const char *filename)
Definition: test_utils.c:432
static int expected[NUM_THREADS]
int PAPI_reset(int EventSet)
Definition: papi.c:2459
#define PAPI_VER_CURRENT
Definition: fpapi.h:14
#define CODE_UNIMPLEMENTED
Definition: testcode.h:2
int main(int argc, char **argv)
Definition: papi_br_prc.c:25
int retval
Definition: zero_fork.c:53
Return codes and api definitions.
void test_skip(const char *file, int line, const char *call, int retval)
Definition: test_utils.c:561
int PAPI_add_named_event(int EventSet, const char *EventName)
Definition: papi.c:1876
int PAPI_library_init(int version)
Definition: papi.c:500
void PAPI_shutdown(void)
Definition: papi.c:4461
int quiet
Definition: rapl_overflow.c:18
#define PAPI_NULL
Definition: fpapi.h:13
int PAPI_create_eventset(int *EventSet)
Definition: papi.c:1464
int branches_testcode(void)
static int total
Definition: rapl_overflow.c:9
int tests_quiet(int argc, char **argv)
Definition: test_utils.c:376
void test_fail(const char *file, int line, const char *call, int retval)
Definition: test_utils.c:468
int PAPI_start(int EventSet)
Definition: papi.c:2096
static long count
int i
Definition: fileop.c:140