perflab added

This commit is contained in:
2025-04-12 10:18:45 +08:00
parent a04c35be04
commit 4ea99d81a7
51 changed files with 350295 additions and 0 deletions

302
perflab/poly/poly_test.c Normal file
View 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;
}