|
Packit |
577717 |
/* This file attempts to test the predicted correctly branches */
|
|
Packit |
577717 |
/* performance event as counted by PAPI_BR_PRC */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Ideally this event should measure */
|
|
Packit |
577717 |
/* predicted correctly *conditional* branches */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* If that's not available, then use total branches. */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* by Vince Weaver, <vincent.weaver@maine.edu> */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#include <stdlib.h>
|
|
Packit |
577717 |
#include <stdio.h>
|
|
Packit |
577717 |
#include <unistd.h>
|
|
Packit |
577717 |
#include <string.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 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int main(int argc, char **argv) {
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int num_runs=100,i;
|
|
Packit |
577717 |
int num_random_branches=500000;
|
|
Packit |
577717 |
long long high=0,low=0,average=0,expected=1500000;
|
|
Packit |
577717 |
long long expected_high,expected_low;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
long long count,total=0;
|
|
Packit |
577717 |
int quiet=0,retval,ins_result;
|
|
Packit |
577717 |
int total_eventset=PAPI_NULL,miss_eventset=PAPI_NULL;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
quiet=tests_quiet(argc,argv);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (!quiet) {
|
|
Packit |
577717 |
printf("\nTesting the PAPI_BR_PRC event.\n\n");
|
|
Packit |
577717 |
printf("This should measure predicted correctly conditional branches\n");
|
|
Packit |
577717 |
printf("If such a counter is not available, it may report predicted correctly\n");
|
|
Packit |
577717 |
printf("total branches instead.\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 |
/* Create total eventset */
|
|
Packit |
577717 |
retval=PAPI_create_eventset(&total_eventset);
|
|
Packit |
577717 |
if (retval!=PAPI_OK) {
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "PAPI_create_eventset", retval );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
retval=PAPI_add_named_event(total_eventset,"PAPI_BR_CN");
|
|
Packit |
577717 |
if (retval!=PAPI_OK) {
|
|
Packit |
577717 |
if (!quiet) printf("Could not add PAPI_BR_CN\n");
|
|
Packit |
577717 |
//test_skip( __FILE__, __LINE__, "adding PAPI_BR_CN", retval );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
retval=PAPI_add_named_event(total_eventset,"PAPI_BR_INS");
|
|
Packit |
577717 |
if (retval!=PAPI_OK) {
|
|
Packit |
577717 |
if (!quiet) printf("Could not add PAPI_BR_INS\n");
|
|
Packit |
577717 |
test_skip( __FILE__, __LINE__, "adding PAPI_BR_INS", retval );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Create correct eventset */
|
|
Packit |
577717 |
retval=PAPI_create_eventset(&miss_eventset);
|
|
Packit |
577717 |
if (retval!=PAPI_OK) {
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "PAPI_create_eventset", retval );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
retval=PAPI_add_named_event(miss_eventset,"PAPI_BR_PRC");
|
|
Packit |
577717 |
if (retval!=PAPI_OK) {
|
|
Packit |
577717 |
if (!quiet) printf("Could not add PAPI_BR_PRC\n");
|
|
Packit |
577717 |
test_skip( __FILE__, __LINE__, "adding PAPI_BR_PRC", retval );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (!quiet) {
|
|
Packit |
577717 |
printf("\nPart 1: Testing that easy to predict loop has few misses\n");
|
|
Packit |
577717 |
printf("Testing a loop with %lld branches (%d times):\n",
|
|
Packit |
577717 |
expected,num_runs);
|
|
Packit |
577717 |
printf("\tOn a simple loop like this, "
|
|
Packit |
577717 |
"hit rate should be very high.\n");
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for(i=0;i
|
|
Packit |
577717 |
|
|
Packit |
577717 |
PAPI_reset(miss_eventset);
|
|
Packit |
577717 |
PAPI_start(miss_eventset);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
ins_result=branches_testcode();
|
|
Packit |
577717 |
|
|
Packit |
577717 |
retval=PAPI_stop(miss_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 (retval!=PAPI_OK) {
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__,
|
|
Packit |
577717 |
"reading PAPI_TOT_INS", retval );
|
|
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 |
if (!quiet) printf("\tAverage number of branch hits: %lld\n",average);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (average
|
|
Packit |
577717 |
if (!quiet) printf("Branch miss rate too high\n");
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "Error too high", 1 );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*******************/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (!quiet) {
|
|
Packit |
577717 |
printf("\nPart 2\n");
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
high=0; low=0; total=0;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for(i=0;i
|
|
Packit |
577717 |
PAPI_reset(total_eventset);
|
|
Packit |
577717 |
PAPI_start(total_eventset);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
ins_result=random_branches_testcode(num_random_branches,1);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
retval=PAPI_stop(total_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 (retval!=PAPI_OK) {
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__,
|
|
Packit |
577717 |
"reading PAPI_TOT_INS", retval );
|
|
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 |
expected=average;
|
|
Packit |
577717 |
if (!quiet) {
|
|
Packit |
577717 |
printf("\nTesting a function that branches "
|
|
Packit |
577717 |
"based on a random number\n");
|
|
Packit |
577717 |
printf(" The loop has %lld conditional branches.\n",expected);
|
|
Packit |
577717 |
printf(" %d are random branches.\n",num_random_branches);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
high=0; low=0; total=0;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for(i=0;i
|
|
Packit |
577717 |
PAPI_reset(miss_eventset);
|
|
Packit |
577717 |
PAPI_start(miss_eventset);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
ins_result=random_branches_testcode(num_random_branches,1);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
retval=PAPI_stop(miss_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 (retval!=PAPI_OK) {
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__,
|
|
Packit |
577717 |
"reading eventset", retval );
|
|
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 |
expected_low=expected-((num_random_branches/4)*3);
|
|
Packit |
577717 |
expected_high=expected-(num_random_branches/4);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (!quiet) {
|
|
Packit |
577717 |
printf("\nOut of %lld branches, "
|
|
Packit |
577717 |
"%lld were correctly predicted\n",expected,average);
|
|
Packit |
577717 |
printf("Assuming a good random number generator and no "
|
|
Packit |
577717 |
"freaky luck\n");
|
|
Packit |
577717 |
printf("The mispredicts should be roughly "
|
|
Packit |
577717 |
"between %lld and %lld\n",
|
|
Packit |
577717 |
expected_low,expected_high);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( average < expected_low) {
|
|
Packit |
577717 |
if (!quiet) printf("Branch hits too low\n");
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "Error too low", 1 );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (average > expected_high) {
|
|
Packit |
577717 |
if (!quiet) printf("Branch hits too high\n");
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "Error too high", 1 );
|
|
Packit |
577717 |
}
|
|
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 |
|
|
Packit |
577717 |
}
|