|
Packit |
577717 |
/* This file attempts to test the retired instruction event */
|
|
Packit |
577717 |
/* As implemented by PAPI_TOT_INS */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* For more info on the causes of overcount on x86 systems */
|
|
Packit |
577717 |
/* See the ISPASS2013 paper: */
|
|
Packit |
577717 |
/* "Non-Determinism and Overcount on Modern Hardware */
|
|
Packit |
577717 |
/* Performance Counter Implementations" */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* by Vince Weaver, <vincent.weaver@maine.edu> */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#include <stdlib.h>
|
|
Packit |
577717 |
#include <stdio.h>
|
|
Packit |
577717 |
#include <unistd.h>
|
|
Packit |
577717 |
#include <string.h>
|
|
Packit |
577717 |
#include <errno.h>
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#include "papi.h"
|
|
Packit |
577717 |
#include "papi_test.h"
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#include "display_error.h"
|
|
Packit |
577717 |
#include "testcode.h"
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#define NUM_RUNS 100
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Test a simple loop of 1 million instructions */
|
|
Packit |
577717 |
/* Most implementations should count be correct within 1% */
|
|
Packit |
577717 |
/* This loop in in assembly language, as compiler generated */
|
|
Packit |
577717 |
/* code varies too much. */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static void test_million(int quiet) {
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int i,result,ins_result;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
long long count,high=0,low=0,total=0,average=0;
|
|
Packit |
577717 |
double error;
|
|
Packit |
577717 |
int eventset=PAPI_NULL;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (!quiet) {
|
|
Packit |
577717 |
printf("\nTesting a loop of 1 million instructions (%d times):\n",
|
|
Packit |
577717 |
NUM_RUNS);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
result=PAPI_create_eventset(&eventset);
|
|
Packit |
577717 |
if (result!=PAPI_OK) {
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "PAPI_create_eventset", result );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
result=PAPI_add_named_event(eventset,"PAPI_TOT_INS");
|
|
Packit |
577717 |
if (result!=PAPI_OK) {
|
|
Packit |
577717 |
if (!quiet) printf("Could not add PAPI_TOT_INS\n");
|
|
Packit |
577717 |
test_skip( __FILE__, __LINE__, "adding PAPI_TOT_INS", result );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for(i=0;i
|
|
Packit |
577717 |
|
|
Packit |
577717 |
PAPI_reset(eventset);
|
|
Packit |
577717 |
PAPI_start(eventset);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
ins_result=instructions_million();
|
|
Packit |
577717 |
|
|
Packit |
577717 |
result=PAPI_stop(eventset,&count);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (ins_result==CODE_UNIMPLEMENTED) {
|
|
Packit |
577717 |
fprintf(stderr,"\tCode unimplemented\n");
|
|
Packit |
577717 |
test_skip( __FILE__, __LINE__, "unimplemented", 0);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (result!=PAPI_OK) {
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__,
|
|
Packit |
577717 |
"reading PAPI_TOT_INS", result );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (count>high) high=count;
|
|
Packit |
577717 |
if ((low==0) || (count
|
|
Packit |
577717 |
total+=count;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
average=total/NUM_RUNS;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
error=display_error(average,high,low,1000000ULL,quiet);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ((error > 1.0) || (error<-1.0)) {
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#if defined(__PPC__)
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if(!quiet) {
|
|
Packit |
577717 |
printf("If PPC is off by 50%%, this might be due to\n"
|
|
Packit |
577717 |
"\"folded\" branch instructions on PPC32\n");
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "validation", result );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Test fldcw. Pentium 4 overcounts this instruction */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static void test_fldcw(int quiet) {
|
|
Packit |
577717 |
|
|
Packit |
577717 |
(void)quiet;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#if defined(__i386__) || (defined __x86_64__)
|
|
Packit |
577717 |
int i,result,ins_result;
|
|
Packit |
577717 |
int eventset=PAPI_NULL;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
long long count,high=0,low=0,total=0,average=0;
|
|
Packit |
577717 |
double error;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (!quiet) {
|
|
Packit |
577717 |
printf("\nTesting a fldcw loop of 900,000 instructions (%d times):\n",
|
|
Packit |
577717 |
NUM_RUNS);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
result=PAPI_create_eventset(&eventset);
|
|
Packit |
577717 |
if (result!=PAPI_OK) {
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "PAPI_create_eventset", result );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
result=PAPI_add_named_event(eventset,"PAPI_TOT_INS");
|
|
Packit |
577717 |
if (result!=PAPI_OK) {
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "adding PAPI_TOT_INS", result );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for(i=0;i
|
|
Packit |
577717 |
|
|
Packit |
577717 |
PAPI_reset(eventset);
|
|
Packit |
577717 |
PAPI_start(eventset);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
ins_result=instructions_fldcw();
|
|
Packit |
577717 |
|
|
Packit |
577717 |
result=PAPI_stop(eventset,&count);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (ins_result==CODE_UNIMPLEMENTED) {
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "Code unimplemented", 1 );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (result!=PAPI_OK) {
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "Unexpected error on read", 1 );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (count>high) high=count;
|
|
Packit |
577717 |
if ((low==0) || (count
|
|
Packit |
577717 |
total+=count;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
average=total/NUM_RUNS;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
error=display_error(average,high,low,900000ULL,quiet);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ((error > 1.0) || (error<-1.0)) {
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (!quiet) {
|
|
Packit |
577717 |
printf("On Pentium 4 machines, the fldcw instruction counts as 2.\n");
|
|
Packit |
577717 |
printf("This will lead to an overcount of 22%%\n");
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "Error too high", 1 );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Test rep-prefixed instructions. */
|
|
Packit |
577717 |
/* HW counters count this as one each, not one per repeat */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static void test_rep(int quiet) {
|
|
Packit |
577717 |
|
|
Packit |
577717 |
(void)quiet;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#if defined(__i386__) || (defined __x86_64__)
|
|
Packit |
577717 |
int i,result,ins_result;
|
|
Packit |
577717 |
int eventset=PAPI_NULL;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
long long count,high=0,low=0,total=0,average=0;
|
|
Packit |
577717 |
double error;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if(!quiet) {
|
|
Packit |
577717 |
printf("\nTesting a 16k rep loop (%d times):\n", NUM_RUNS);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
result=PAPI_create_eventset(&eventset);
|
|
Packit |
577717 |
if (result!=PAPI_OK) {
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "PAPI_create_eventset", result );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
result=PAPI_add_named_event(eventset,"PAPI_TOT_INS");
|
|
Packit |
577717 |
if (result!=PAPI_OK) {
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "adding PAPI_TOT_INS", result );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for(i=0;i
|
|
Packit |
577717 |
|
|
Packit |
577717 |
PAPI_reset(eventset);
|
|
Packit |
577717 |
PAPI_start(eventset);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
ins_result=instructions_rep();
|
|
Packit |
577717 |
|
|
Packit |
577717 |
result=PAPI_stop(eventset,&count);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (ins_result==CODE_UNIMPLEMENTED) {
|
|
Packit |
577717 |
fprintf(stderr,"\tCode unimplemented\n");
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "Code unimplemented", 1 );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (result!=PAPI_OK) {
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "Unexpected error on read", 1 );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (count>high) high=count;
|
|
Packit |
577717 |
if ((low==0) || (count
|
|
Packit |
577717 |
total+=count;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
average=total/NUM_RUNS;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
error=display_error(average,high,low,6002,quiet);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ((error > 10.0) || (error<-10.0)) {
|
|
Packit |
577717 |
if (!quiet) {
|
|
Packit |
577717 |
printf("Instruction count off by more than 10%%\n");
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "Error too high", 1 );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int main(int argc, char **argv) {
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int retval;
|
|
Packit |
577717 |
int quiet=0;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
(void)argc;
|
|
Packit |
577717 |
(void)argv;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
quiet=tests_quiet(argc,argv);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (!quiet) {
|
|
Packit |
577717 |
printf("\nThis test checks that the \"PAPI_TOT_INS\" generalized "
|
|
Packit |
577717 |
"event is working.\n");
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Init the PAPI library */
|
|
Packit |
577717 |
retval = PAPI_library_init( PAPI_VER_CURRENT );
|
|
Packit |
577717 |
if ( retval != PAPI_VER_CURRENT ) {
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "PAPI_library_init", retval );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
test_million(quiet);
|
|
Packit |
577717 |
test_fldcw(quiet);
|
|
Packit |
577717 |
test_rep(quiet);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (!quiet) printf("\n");
|
|
Packit |
577717 |
|
|
Packit |
577717 |
test_pass( __FILE__ );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
PAPI_shutdown();
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return 0;
|
|
Packit |
577717 |
}
|