Files
csapp2025/perflab/poly/poly_723005.c
2025-04-17 23:02:23 +08:00

143 lines
3.9 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
常系数多项式计算函数。
通过减少乘法次数和使用位运算优化性能。
公式result = 37 + 72*x + 84*x^2 + 52*x^3
*/
/**************************************************************************
多项式计算函数。按下面的要求编辑此文件:
1. 将你的学号、姓名,以注释的方式写到下面;
2. 实现不同版本的多项式计算函数;
3. 编辑peval_fun_rec peval_fun_tab数组将你的最好的答案
最小CPE、最小C10作为数组的前两项
***************************************************************************/
/*
学号202302723005
姓名:程景愉
*/
#include <stdio.h>
#include <stdlib.h>
typedef int (*peval_fun)(int*, int, int);
typedef struct {
peval_fun f;
char *descr;
} peval_fun_rec, *peval_fun_ptr;
/**************************************************************************
Edit this comment to indicate your name and Andrew ID
#ifdef ASSIGN
Submission by Harry Q. Bovik, bovik@andrew.cmu.edu
#else
Instructor's version.
Created by Randal E. Bryant, Randy.Bryant@cs.cmu.edu, 10/07/02
#endif
***************************************************************************/
/*
实现一个指定的常系数多项式计算
第一次,请直接运行程序,以便获知你需要实现的常系数是啥
*/
int poly_eval(int *a, int degree, int x)
{
int result = 0;
int i;
int xpwr = 1; // x的幂次
for (i = 0; i <= degree; i++) {
result += a[i]*xpwr;
xpwr *= x;
}
return result;
}
/* 多项式计算函数。注意:这个只是一个参考实现,你需要实现自己的版本 */
/*
友情提示lcc支持ATT格式的嵌入式汇编例如
_asm("movl %eax,%ebx");
_asm("pushl %edx");
可以在lcc中project->configuration->Compiler->Code Generation->Generate .asm
将其选中后可以在lcc目录下面生成对应程序的汇编代码实现。通过查看汇编文件
你可以了解编译器是如何实现你的代码的。有些实现可能非常低效。
你可以在适当的地方加入嵌入式汇编,来大幅度提高计算性能。
*/
int const_poly_eval(int *not_use, int not_use2, int x)
{
register int result = 0;
register int x1, x2, x3;
register int tmp = x; // tmp = x
register int tmp1 = tmp * tmp; // tmp1 = x^2
register int tmp2 = tmp1 * tmp;// tmp2 = x^3
// 计算72x: 64x + 8x = (x << 6) + (x << 3)
x1 = (tmp << 6) + (tmp << 3);
// 计算84x^2: 64x2 + 16x2 + 4x2 = (x2 << 6) + (x2 << 4) + (x2 << 2)
x2 = (tmp1 << 6) + (tmp1 << 4) + (tmp1 << 2);
// 计算52x^3: 32x3 + 16x3 + 4x3 = (x3 << 5) + (x3 << 4) + (x3 << 2)
x3 = (tmp2 << 5) + (tmp2 << 4) + (tmp2 << 2);
// 合并结果37 + 72x + 84x2 + 52x3
result = 37 + x1 + x2 + x3;
return result;
}
int poly_eval12(int* a, int degree, int x) {
if (degree == 10) {
// 针对10阶完全展开霍纳法则保持原逻辑不变
int result = a[10];
result = result * x + a[9];
result = result * x + a[8];
result = result * x + a[7];
result = result * x + a[6];
result = result * x + a[5];
result = result * x + a[4];
result = result * x + a[3];
result = result * x + a[2];
result = result * x + a[1];
return result * x + a[0];
} else {
// 通用版本处理其他阶数(保持原逻辑不变)
int result = 0;
int x2 = x * x;
int i = degree;
for (; i > 0; i -= 2) {
result = result * x2 + a[i] * x + a[i - 1];
}
if (i == 0) {
result = result * x + a[0];
}
return result;
}
}
/*
这个表格包含多个数组元素,每一组元素(函数名字, "描述字符串"
将你认为最好的两个实现,放在最前面。
比如:
{my_poly_eval1, "超级垃圾实现"},
{my_poly_eval2, "好一点的实现"},
*/
peval_fun_rec peval_fun_tab[] =
{
/* 第一项应当是你写的最好CPE的函数实现 */
{poly_eval12, "程景愉的CPE"},
/* 第二项应当是你写的在10阶时具有最好性能的实现 */
{poly_eval12, "程景愉的10阶实现"},
{poly_eval, "poly_eval: 参考实现"},
/* 下面的代码不能修改或者删除!!表明数组列表结束 */
{NULL, ""}
};