Blame src/validation_tests/papi_tot_ins.c

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
}