304 lines
7.7 KiB
C
304 lines
7.7 KiB
C
/* Test setup for polynomial evaluation. Do not change this. */
|
||
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <string.h>
|
||
#include <time.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;
|
||
}
|