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 // 这是我的处理器主频
/* 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} /* 常系数多项式计算 */
};
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("你需要修改poly.c的const_poly_eval函数实现下面的常数多项式计算\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("常系数多项式计算const_poly_eval实现错误x=%d预期结果是%d但是计算得到的是%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(" 常系数多项式计算时间 = %.1f\n", fix_time);
printf(" 最高的常系数多项式计算得分 ============== %.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,
"错误!多项式计算不对!阶=%d时计算的值是%d而正确值是%d\n",
MAXDEGREE-i, v, pval[i]);
}
}
}
v = f(coeff, FIXDEGREE, xval);
if (v != fixval) {
ok = 0;
if (rpt) {
fprintf(rpt,
"错误!多项式计算不对!阶=%d时计算的值是%d而正确值是%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("函数:%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);
}
/* 产生一个0~divv-1之间的随机数同时更新随机数种子 */
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多项式优化实验欢迎你\n");
printf("============================\n");
if (argc == 1)
{
printf("使用方法:%s 学号后6位 [学号后6位] [学号后6位] ...\n",argv[0]);
printf("你需要依据提示改写poly.c程序实现一个常系数多项式的计算尽可能快哦....\n");
printf("另外你需要改写poly.c程序实现任意阶的多项式计算和10阶的多项式计算要快\n");
return 0;
}
/*依据学号,初始化一个随机数发生器*/
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(" 最高的CPE得分 =========================== %.0f\n",
compute_score(cpe, cstandard[0].cref, cstandard[0].cbest));
if (i == 1)
printf(" 最高的C(10)得分 ========================= %.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;
}