perflab added
This commit is contained in:
302
perflab/poly/poly_test.c
Normal file
302
perflab/poly/poly_test.c
Normal file
@ -0,0 +1,302 @@
|
||||
/* Test setup for polynomial evaluation. Do not change this. */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
//#include <random.h>
|
||||
#include "poly.h"
|
||||
#include "cpe.h"
|
||||
#include "clock.h"
|
||||
|
||||
double CPU_Mhz;
|
||||
|
||||
/* Degree for fixed evaluation */
|
||||
#define FIXDEGREE 10
|
||||
/* Largest degree polynomial tested */
|
||||
#define MAXDEGREE 2000
|
||||
static int coeff[MAXDEGREE+1];
|
||||
|
||||
#define MAX_ITER_COUNT 100
|
||||
|
||||
#define REF_CPU_MHZ 2292.6 // <20><><EFBFBD><EFBFBD><EFBFBD>ҵĴ<D2B5><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ
|
||||
|
||||
/* Define performance standards */
|
||||
static struct {
|
||||
double cref; /* Cycles taken by reference solution */
|
||||
double cbest; /* Cycles taken by our best implementation */
|
||||
} cstandard[3] =
|
||||
{{4.00, 1.75}, /* CPE */
|
||||
{50, 43}, /* C(10) */
|
||||
{57,31} /* <20><>ϵ<EFBFBD><CFB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD> */
|
||||
};
|
||||
|
||||
int coeff_const[4];
|
||||
|
||||
/* Should I print extra information? */
|
||||
int verbose = 0;
|
||||
|
||||
/* Standard value for polynomial evaluation */
|
||||
static int xval;
|
||||
|
||||
/* How many degrees should I compute reference value for? */
|
||||
#define DCNT 20
|
||||
|
||||
/* Correct value of polynomial evaluation for range of different degrees */
|
||||
/* pval[i] contains evaluation for degree MAXDEGREE-i */
|
||||
static int pval[DCNT];
|
||||
/* fixval contains evaluation for degree FIXDEGREE */
|
||||
static int fixval;
|
||||
static int fixval_const;
|
||||
|
||||
static void init_const_poly(void);
|
||||
static void init(void);
|
||||
extern int const_poly_eval(int *not_use, int not_use2, int x);
|
||||
void run_fun_const(int degree);
|
||||
static double compute_score(double cmeas, double cref, double cbest);
|
||||
unsigned long rand1_h,rand1_l,rand_div;
|
||||
void rand_step(unsigned long divv);
|
||||
void GenerateRandomNumber(unsigned long divv);
|
||||
extern void make_CPU_busy(void);
|
||||
double run_poly_perf_test(void);
|
||||
|
||||
/* Reference implementation */
|
||||
static int ref_poly_eval(int *a, int degree, int x)
|
||||
{
|
||||
int result = 0;
|
||||
int i;
|
||||
int xpwr = 1; /* Successive powers of x */
|
||||
for (i = 0; i <= degree; i++) {
|
||||
result += a[i]*xpwr;
|
||||
xpwr *= x;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Initialize polynomial to constant values and compute reference values */
|
||||
static void init_const_poly(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0;i<4;i++)
|
||||
{
|
||||
GenerateRandomNumber(90);
|
||||
coeff_const[i] = rand_div+10;
|
||||
}
|
||||
|
||||
printf("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD>poly.c<><63>const_poly_eval<61><6C><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ij<EFBFBD><C4B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD>㣡\n");
|
||||
printf("\tresult=%d+%d*x+%d*x^2+%d*x^3\n",coeff_const[0],coeff_const[1],coeff_const[2],coeff_const[3]);
|
||||
|
||||
fixval_const = ref_poly_eval(coeff_const, 3, xval);
|
||||
// printf("x=%d, fixval_const=%d\n",xval,fixval_const);
|
||||
|
||||
}
|
||||
|
||||
void test_const_poly(void)
|
||||
{
|
||||
int i;
|
||||
double fix_time=0;
|
||||
int my_cal = const_poly_eval(coeff_const, 3, xval);
|
||||
if (fixval_const != my_cal)
|
||||
{
|
||||
printf("<EFBFBD><EFBFBD>ϵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>const_poly_evalʵ<EFBFBD>ִ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>x=%d<><64><EFBFBD><EFBFBD>Ԥ<EFBFBD>ڽ<EFBFBD><DABD><EFBFBD><EFBFBD><EFBFBD>%d<><64><EFBFBD><EFBFBD><EFBFBD>Ǽ<EFBFBD><C7BC><EFBFBD><EFBFBD>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD>%d\n",xval,fixval_const,my_cal);
|
||||
exit(0);
|
||||
}
|
||||
fix_time = 0;
|
||||
for (i=0;i<MAX_ITER_COUNT;i++)
|
||||
fix_time += measure_function(run_fun_const, 3);
|
||||
fix_time = fix_time / MAX_ITER_COUNT;
|
||||
printf(" <20><>ϵ<EFBFBD><CFB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1> = %.1f\n", fix_time);
|
||||
printf(" <20><><EFBFBD>ߵij<DFB5>ϵ<EFBFBD><CFB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD><EFBFBD>÷<EFBFBD> ============== %.0f\n",
|
||||
compute_score(fix_time, cstandard[2].cref, cstandard[2].cbest));
|
||||
}
|
||||
|
||||
/* Initialize polynomial to random values and compute reference values */
|
||||
static void init(void)
|
||||
{
|
||||
int i;
|
||||
xval = rand();
|
||||
for (i = 0; i <= MAXDEGREE; i++)
|
||||
coeff[i] = rand();
|
||||
for (i = 0; i < DCNT; i++)
|
||||
pval[i] = ref_poly_eval(coeff, MAXDEGREE-i, xval);
|
||||
fixval = ref_poly_eval(coeff, FIXDEGREE, xval);
|
||||
}
|
||||
|
||||
/* Test function on standard test cases. */
|
||||
int test_poly(peval_fun f, FILE *rpt) {
|
||||
int i;
|
||||
int v;
|
||||
int ok = 1;
|
||||
for (i = 0; i < DCNT; i++) {
|
||||
v = f(coeff, MAXDEGREE-i, xval);
|
||||
if (v != pval[i]) {
|
||||
ok = 0;
|
||||
if (rpt) {
|
||||
fprintf(rpt,
|
||||
"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><EFBFBD><EFBFBD>㲻<EFBFBD>ԣ<EFBFBD><EFBFBD><EFBFBD>=%dʱ<64><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5>%d<><64><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȷֵ<C8B7><D6B5>%d\n",
|
||||
MAXDEGREE-i, v, pval[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
v = f(coeff, FIXDEGREE, xval);
|
||||
if (v != fixval) {
|
||||
ok = 0;
|
||||
if (rpt) {
|
||||
fprintf(rpt,
|
||||
"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><EFBFBD><EFBFBD>㲻<EFBFBD>ԣ<EFBFBD><EFBFBD><EFBFBD>=%dʱ<64><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5>%d<><64><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȷֵ<C8B7><D6B5>%d\n",
|
||||
FIXDEGREE, v, fixval);
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
/* Fit into framework of cpe measuring code */
|
||||
static peval_fun pfun;
|
||||
|
||||
volatile int sink;
|
||||
/* Run pfun for given degree */
|
||||
void run_fun(int degree)
|
||||
{
|
||||
sink = pfun(coeff, degree, xval);
|
||||
}
|
||||
|
||||
volatile int sink_const;
|
||||
/* Run pfun for given degree */
|
||||
void run_fun_const(int degree)
|
||||
{
|
||||
sink_const = const_poly_eval(coeff_const, degree, xval);
|
||||
}
|
||||
|
||||
|
||||
/* Test and measure polynomial evaluation function. Set values
|
||||
of CPE and CFIX */
|
||||
void run_poly(peval_fun f, char *descr, double *cpep, double *cfixp)
|
||||
{
|
||||
int i;
|
||||
double cpe=0;
|
||||
double fix_time=0;
|
||||
pfun = f;
|
||||
printf("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>%s\n", descr);
|
||||
if (test_poly(f, stdout)) {
|
||||
cpe = 0;
|
||||
for (i=0;i<MAX_ITER_COUNT;i++)
|
||||
cpe += find_cpe(run_fun, MAXDEGREE);
|
||||
cpe = cpe/MAX_ITER_COUNT;
|
||||
fix_time = 0;
|
||||
for (i=0;i<MAX_ITER_COUNT;i++)
|
||||
fix_time += measure_function(run_fun, FIXDEGREE);
|
||||
fix_time = fix_time/MAX_ITER_COUNT;
|
||||
printf(" CPE = %.2f\tC(%d) = %.1f\n", cpe,
|
||||
FIXDEGREE, fix_time);
|
||||
if (cpep)
|
||||
*cpep = cpe;
|
||||
if (cfixp)
|
||||
*cfixp = fix_time;
|
||||
}
|
||||
}
|
||||
|
||||
/* Compute the grade achieved by function */
|
||||
static double compute_score(double cmeas, double cref, double cbest)
|
||||
{
|
||||
double sbest = cref/cbest;
|
||||
double smeas = cref/cmeas;
|
||||
if (smeas < 0.1*(sbest-1)+1)
|
||||
return 0;
|
||||
if (smeas > 1.1*(sbest-1)+1)
|
||||
return 120;
|
||||
return 100*((smeas-1.0)/(sbest-1.0) + 0.1);
|
||||
}
|
||||
|
||||
/* <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>0~divv-1֮<31><D6AE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬʱ<CDAC><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
||||
void GenerateRandomNumber(unsigned long divv)
|
||||
{
|
||||
unsigned long long x = rand1_h;
|
||||
x *= 0x6AC690C5;
|
||||
x += rand1_l;
|
||||
|
||||
rand1_h = (unsigned long)x;
|
||||
rand1_l = (unsigned long)(x>>32);
|
||||
if (divv==0) return;
|
||||
|
||||
rand_div = rand1_h % divv;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
double cpe = cstandard[0].cref;
|
||||
double cfix = cstandard[1].cref;
|
||||
verbose = 0;
|
||||
srand((unsigned int)time(NULL));
|
||||
|
||||
// CPU_Factor();
|
||||
// GetCpuClock();
|
||||
printf("\t2015<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD>Ż<EFBFBD>ʵ<EFBFBD>飬<EFBFBD><EFBFBD>ӭ<EFBFBD>㣡\n");
|
||||
printf("============================\n");
|
||||
|
||||
if (argc == 1)
|
||||
{
|
||||
printf("ʹ<EFBFBD>÷<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>%s ѧ<>ź<EFBFBD>6λ [ѧ<>ź<EFBFBD>6λ] [ѧ<>ź<EFBFBD>6λ] ...\n",argv[0]);
|
||||
printf("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD>дpoly.c<><63><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>ϵ<EFBFBD><CFB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD>ļ<EFBFBD><C4BC>㣬<EFBFBD><E3A3AC><EFBFBD><EFBFBD><EFBFBD>ܿ<EFBFBD>Ŷ....\n");
|
||||
printf("<EFBFBD><EFBFBD><EFBFBD>⣬<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD>дpoly.c<><63><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ķ<D7B5><C4B6><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>10<31>Ķ<D7B5><C4B6><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD>㣬Ҫ<E3A3AC>죡\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*<2A><><EFBFBD><EFBFBD>ѧ<EFBFBD>ţ<EFBFBD><C5A3><EFBFBD>ʼ<EFBFBD><CABC>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
rand1_h = (unsigned long)atoi(argv[1]);
|
||||
rand1_l=0x29A;
|
||||
GenerateRandomNumber(0);
|
||||
for (i=2;i<argc;i++)
|
||||
{
|
||||
rand1_l = (unsigned long)atoi(argv[i]);
|
||||
GenerateRandomNumber(0);
|
||||
}
|
||||
|
||||
GenerateRandomNumber(50);
|
||||
//srand(rand_div);
|
||||
|
||||
//make_CPU_busy();
|
||||
//CPU_Mhz=mhz(1);
|
||||
init();
|
||||
init_const_poly();
|
||||
printf("============================\n");
|
||||
//make_CPU_busy();
|
||||
//run_poly_perf_test();
|
||||
test_const_poly();
|
||||
for (i = 0; peval_fun_tab[i].f != NULL; i++) {
|
||||
//make_CPU_busy();
|
||||
run_poly(peval_fun_tab[i].f, peval_fun_tab[i].descr, &cpe, &cfix);
|
||||
if (i == 0)
|
||||
printf(" <20><><EFBFBD>ߵ<EFBFBD>CPE<50>÷<EFBFBD> =========================== %.0f\n",
|
||||
compute_score(cpe, cstandard[0].cref, cstandard[0].cbest));
|
||||
if (i == 1)
|
||||
printf(" <20><><EFBFBD>ߵ<EFBFBD>C(10)<29>÷<EFBFBD> ========================= %.0f\n",
|
||||
compute_score(cfix, cstandard[1].cref, cstandard[1].cbest));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int poly_eval_perf_test(int *a, int degree, int x)
|
||||
{
|
||||
int result = 0;
|
||||
int i;
|
||||
int xpwr = 1; /* Successive powers of x */
|
||||
for (i = 0; i <= degree; i++) {
|
||||
result += a[i] * xpwr;
|
||||
xpwr *= x;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
double run_poly_perf_test(void)
|
||||
{
|
||||
int i;
|
||||
double fix_time=0;
|
||||
pfun = poly_eval_perf_test;
|
||||
for (i=0;i<MAX_ITER_COUNT;i++)
|
||||
fix_time += measure_function(run_fun, FIXDEGREE);
|
||||
fix_time = fix_time/MAX_ITER_COUNT;
|
||||
printf("fix_time=%f\n",fix_time);
|
||||
return fix_time;
|
||||
}
|
||||
Reference in New Issue
Block a user