PAPI 7.1.0.0
Loading...
Searching...
No Matches
papi_tot_ins.c
Go to the documentation of this file.
1/* This file attempts to test the retired instruction event */
2/* As implemented by PAPI_TOT_INS */
3
4/* For more info on the causes of overcount on x86 systems */
5/* See the ISPASS2013 paper: */
6/* "Non-Determinism and Overcount on Modern Hardware */
7/* Performance Counter Implementations" */
8
9/* by Vince Weaver, <vincent.weaver@maine.edu> */
10
11#include <stdlib.h>
12#include <stdio.h>
13#include <unistd.h>
14#include <string.h>
15#include <errno.h>
16
17#include "papi.h"
18#include "papi_test.h"
19
20#include "display_error.h"
21#include "testcode.h"
22
23#define NUM_RUNS 100
24
25
26 /* Test a simple loop of 1 million instructions */
27 /* Most implementations should count be correct within 1% */
28 /* This loop in in assembly language, as compiler generated */
29 /* code varies too much. */
30
31static void test_million(int quiet) {
32
33 int i,result,ins_result;
34
35 long long count,high=0,low=0,total=0,average=0;
36 double error;
37 int eventset=PAPI_NULL;
38
39 if (!quiet) {
40 printf("\nTesting a loop of 1 million instructions (%d times):\n",
41 NUM_RUNS);
42 }
43
45 if (result!=PAPI_OK) {
46 test_fail( __FILE__, __LINE__, "PAPI_create_eventset", result );
47 }
48
49 result=PAPI_add_named_event(eventset,"PAPI_TOT_INS");
50 if (result!=PAPI_OK) {
51 if (!quiet) printf("Could not add PAPI_TOT_INS\n");
52 test_skip( __FILE__, __LINE__, "adding PAPI_TOT_INS", result );
53 }
54
55 for(i=0;i<NUM_RUNS;i++) {
56
57 PAPI_reset(eventset);
58 PAPI_start(eventset);
59
60 ins_result=instructions_million();
61
62 result=PAPI_stop(eventset,&count);
63
64 if (ins_result==CODE_UNIMPLEMENTED) {
65 fprintf(stderr,"\tCode unimplemented\n");
66 test_skip( __FILE__, __LINE__, "unimplemented", 0);
67 }
68
69 if (result!=PAPI_OK) {
70 test_fail( __FILE__, __LINE__,
71 "reading PAPI_TOT_INS", result );
72 }
73
74 if (count>high) high=count;
75 if ((low==0) || (count<low)) low=count;
76 total+=count;
77 }
78
79 average=total/NUM_RUNS;
80
81 error=display_error(average,high,low,1000000ULL,quiet);
82
83 if ((error > 1.0) || (error<-1.0)) {
84
85#if defined(__PPC__)
86
87 if(!quiet) {
88 printf("If PPC is off by 50%%, this might be due to\n"
89 "\"folded\" branch instructions on PPC32\n");
90 }
91#endif
92 test_fail( __FILE__, __LINE__, "validation", result );
93
94 }
95}
96
97/* Test fldcw. Pentium 4 overcounts this instruction */
98
99static void test_fldcw(int quiet) {
100
101 (void)quiet;
102
103#if defined(__i386__) || (defined __x86_64__)
104 int i,result,ins_result;
105 int eventset=PAPI_NULL;
106
107 long long count,high=0,low=0,total=0,average=0;
108 double error;
109
110 if (!quiet) {
111 printf("\nTesting a fldcw loop of 900,000 instructions (%d times):\n",
112 NUM_RUNS);
113 }
114
115 result=PAPI_create_eventset(&eventset);
116 if (result!=PAPI_OK) {
117 test_fail( __FILE__, __LINE__, "PAPI_create_eventset", result );
118 }
119
120 result=PAPI_add_named_event(eventset,"PAPI_TOT_INS");
121 if (result!=PAPI_OK) {
122 test_fail( __FILE__, __LINE__, "adding PAPI_TOT_INS", result );
123 }
124
125 for(i=0;i<NUM_RUNS;i++) {
126
127 PAPI_reset(eventset);
128 PAPI_start(eventset);
129
130 ins_result=instructions_fldcw();
131
132 result=PAPI_stop(eventset,&count);
133
134 if (ins_result==CODE_UNIMPLEMENTED) {
135 test_fail( __FILE__, __LINE__, "Code unimplemented", 1 );
136 }
137
138 if (result!=PAPI_OK) {
139 test_fail( __FILE__, __LINE__, "Unexpected error on read", 1 );
140 }
141
142 if (count>high) high=count;
143 if ((low==0) || (count<low)) low=count;
144 total+=count;
145 }
146
147 average=total/NUM_RUNS;
148
149 error=display_error(average,high,low,900000ULL,quiet);
150
151 if ((error > 1.0) || (error<-1.0)) {
152
153 if (!quiet) {
154 printf("On Pentium 4 machines, the fldcw instruction counts as 2.\n");
155 printf("This will lead to an overcount of 22%%\n");
156 }
157 test_fail( __FILE__, __LINE__, "Error too high", 1 );
158 }
159#endif
160}
161
162/* Test rep-prefixed instructions. */
163/* HW counters count this as one each, not one per repeat */
164
165static void test_rep(int quiet) {
166
167 (void)quiet;
168
169#if defined(__i386__) || (defined __x86_64__)
170 int i,result,ins_result;
171 int eventset=PAPI_NULL;
172
173 long long count,high=0,low=0,total=0,average=0;
174 double error;
175
176 if(!quiet) {
177 printf("\nTesting a 16k rep loop (%d times):\n", NUM_RUNS);
178 }
179
180 result=PAPI_create_eventset(&eventset);
181 if (result!=PAPI_OK) {
182 test_fail( __FILE__, __LINE__, "PAPI_create_eventset", result );
183 }
184
185 result=PAPI_add_named_event(eventset,"PAPI_TOT_INS");
186 if (result!=PAPI_OK) {
187 test_fail( __FILE__, __LINE__, "adding PAPI_TOT_INS", result );
188 }
189
190 for(i=0;i<NUM_RUNS;i++) {
191
192 PAPI_reset(eventset);
193 PAPI_start(eventset);
194
195 ins_result=instructions_rep();
196
197 result=PAPI_stop(eventset,&count);
198
199 if (ins_result==CODE_UNIMPLEMENTED) {
200 fprintf(stderr,"\tCode unimplemented\n");
201 test_fail( __FILE__, __LINE__, "Code unimplemented", 1 );
202 }
203
204 if (result!=PAPI_OK) {
205 test_fail( __FILE__, __LINE__, "Unexpected error on read", 1 );
206 }
207
208 if (count>high) high=count;
209 if ((low==0) || (count<low)) low=count;
210 total+=count;
211 }
212
213 average=total/NUM_RUNS;
214
215 error=display_error(average,high,low,6002,quiet);
216
217 if ((error > 10.0) || (error<-10.0)) {
218 if (!quiet) {
219 printf("Instruction count off by more than 10%%\n");
220 }
221 test_fail( __FILE__, __LINE__, "Error too high", 1 );
222 }
223#endif
224}
225
226int main(int argc, char **argv) {
227
228 int retval;
229 int quiet=0;
230
231 (void)argc;
232 (void)argv;
233
234 quiet=tests_quiet(argc,argv);
235
236 if (!quiet) {
237 printf("\nThis test checks that the \"PAPI_TOT_INS\" generalized "
238 "event is working.\n");
239 }
240
241 /* Init the PAPI library */
243 if ( retval != PAPI_VER_CURRENT ) {
244 test_fail( __FILE__, __LINE__, "PAPI_library_init", retval );
245 }
246
250
251 if (!quiet) printf("\n");
252
253 test_pass( __FILE__ );
254
256
257 return 0;
258}
volatile int result
int i
static long count
add PAPI preset or native hardware event by name to an EventSet
Create a new empty PAPI EventSet.
initialize the PAPI library.
Reset the hardware event counts in an event set.
Finish using PAPI and free all related resources.
Start counting hardware events in an event set.
Stop counting hardware events in an event set.
double display_error(long long average, long long high, long long low, long long expected, int quiet)
Definition: display_error.c:7
#define PAPI_VER_CURRENT
Definition: f90papi.h:54
#define PAPI_OK
Definition: f90papi.h:73
#define PAPI_NULL
Definition: f90papi.h:78
int instructions_fldcw(void)
int instructions_rep(void)
int instructions_million(void)
Return codes and api definitions.
FILE * stderr
int tests_quiet(int argc, char **argv)
Definition: test_utils.c:376
void PAPI_NORETURN test_fail(const char *file, int line, const char *call, int retval)
Definition: test_utils.c:491
void PAPI_NORETURN test_pass(const char *filename)
Definition: test_utils.c:432
void PAPI_NORETURN test_skip(const char *file, int line, const char *call, int retval)
Definition: test_utils.c:584
static void test_fldcw(int quiet)
Definition: papi_tot_ins.c:99
static void test_rep(int quiet)
Definition: papi_tot_ins.c:165
#define NUM_RUNS
Definition: papi_tot_ins.c:23
static void test_million(int quiet)
Definition: papi_tot_ins.c:31
int main()
Definition: pernode.c:20
int quiet
Definition: rapl_overflow.c:19
static int total
Definition: rapl_overflow.c:9
#define CODE_UNIMPLEMENTED
Definition: testcode.h:2
int retval
Definition: zero_fork.c:53