CSAPP:性能优化实验

poly.c

/**************************************************************************
	多项式计算函数。按下面的要求编辑此文件:
	1. 将你的学号、姓名,以注释的方式写到下面;
	2. 实现不同版本的多项式计算函数;
	3. 编辑peval_fun_rec peval_fun_tab数组,将你的最好的答案
		(最小CPE、最小C10)作为数组的前两项
***************************************************************************/
#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 const_poly_eval(int *not_use, int not_use2, int x)
{
	int x64,x32,x16,x8,x4,x2;
	x64 = x << 6;
	x32 = x << 5;
	x16 = x << 4;
	x8 = x << 3;
	x4 = x << 2;
	x2 = x << 1;
    return 25 + (x64+x32) + ((x32-x) + (x32-x4)*x)*x;
}


/* 多项式计算函数。注意:这个只是一个参考实现,你需要实现自己的版本 */

/*
	友情提示:lcc支持ATT格式的嵌入式汇编,例如

	_asm("movl %eax,%ebx");
	_asm("pushl %edx");

	可以在lcc中project->configuration->Compiler->Code Generation->Generate .asm,
	将其选中后,可以在lcc目录下面生成对应程序的汇编代码实现。通过查看汇编文件,
	你可以了解编译器是如何实现你的代码的。有些实现可能非常低效。
	你可以在适当的地方加入嵌入式汇编,来大幅度提高计算性能。
*/

int my_poly_eval1(int *a, int degree, int x)
{
    int result=0;
	int xp[11];
	int i;

	xp[0]=1;
	xp[1]=x;
	xp[2]=xp[1]*x;
	xp[3]=xp[2]*x;
	xp[4]=xp[3]*x;
	xp[5]=xp[4]*x;
	xp[6]=xp[5]*x;
	xp[7]=xp[6]*x;
	xp[8]=xp[7]*x;
	xp[9]=xp[8]*x;
	xp[10]=xp[9]*x;

	if(degree==10)
		result=a[0]+xp[1]*a[1]+xp[2]*a[2]+xp[3]*a[3]+xp[4]*a[4]+xp[5]*a[5]+xp[6]*a[6]+xp[7]*a[7]+xp[8]*a[8]+xp[9]*a[9]+xp[10]*a[10];
	else
	{
		for(i=degree;i>=9;i-=10)
		{
			result=(a[i-9]+x*a[i-8]+xp[2]*a[i-7]+xp[3]*a[i-6]+xp[4]*a[i-5]+xp[5]*a[i-4]+xp[6]*a[i-3]+xp[7]*a[i-2]+xp[8]*a[i-1]+xp[9]*a[i])+result*xp[10];
		}
		if(i!=-1)
		{
			int tmp=0;
			for(int j=0;j<=i;j++)
				tmp+=a[j]*xp[j];
			result=result*xp[i+1]+tmp;
		}
	}

    return result;
}


/*
	这个表格包含多个数组元素,每一组元素(函数名字, "描述字符串")
	将你认为最好的两个实现,放在最前面。
	比如:
	{my_poly_eval1, "超级垃圾实现"},
	{my_poly_eval2, "好一点的实现"},
*/

peval_fun_rec peval_fun_tab[] =
{

	/* 第一项,应当是你写的最好CPE的函数实现 */
	{my_poly_eval1, "Lane的CPE"},
	/* 第二项,应当是你写的在10阶时具有最好性能的实现 */
	{my_poly_eval1, "Lane的10阶实现"},

	// {poly_eval, "poly_eval: 参考实现"},

	/* 下面的代码不能修改或者删除!!表明数组列表结束 */
	{NULL, ""}
};

rowcol.c

/**************************************************************************
	行/列求和函数。按下面的要求编辑此文件:
	1. 将你的学号、姓名,以注释的方式写到下面;
	2. 实现不同版本的行列求和函数;
	3. 编辑rc_fun_rec rc_fun_tab数组,将你的最好的答案
		(最好的行和列求和、最好的列求和)作为数组的前两项
***************************************************************************/
#include  <stdio.h>
#include  <stdlib.h>
#include  "rowcol.h"
#include  <math.h>

/* 计算矩阵中的每一列的和。请注意对于行和列求和来说,调用参数是
	一样的,只是第2个参数不会用到而已
*/

void my_c_sum1(matrix_t M, vector_t rowsum, vector_t colsum)
{
	int i, j;
    for (j = 0; j < N; j++) 
    {
        colsum[j] = 0;
        // 循环展开,每次处理两个元素
        for (i = 0; i < N - 1; i += 2)
        {
            colsum[j] += M[i][j] + M[i + 1][j];
        }
        // 如果N是奇数,需要处理最后一个元素
        if (i < N)
        {
            colsum[j] += M[i][j];
        }
    }
}


/* 计算矩阵中的每一行、每一列的和。 */

void my_rc_sum2(matrix_t M, vector_t rowsum, vector_t colsum)
{
	int i, j;
    for (i = 0; i < N; i++) 
    {
        rowsum[i] = colsum[i] = 0; 
        // 循环展开,每次处理两个元素
        for (j = 0; j < N - 1; j += 2) 
        {
            rowsum[i] += M[i][j] + M[i][j + 1];
            colsum[i] += M[j][i] + M[j + 1][i];
        }
        // 如果N是奇数,需要处理最后一个元素
        if (j < N)
        {
            rowsum[i] += M[i][j];
            colsum[i] += M[j][i];
        }
    }
}



/* 
	这个表格包含多个数组元素,每一组元素(函数名字, COL/ROWCOL, "描述字符串")
	COL表示该函数仅仅计算每一列的和
	ROWCOL表示该函数计算每一行、每一列的和
	将你认为最好的两个实现,放在最前面。
	比如:
	{my_c_sum1, "超级垃圾列求和实现"},
	{my_rc_sum2, "好一点的行列求和实现"},
*/

rc_fun_rec rc_fun_tab[] = 
{

  /* 第一项,应当是你写的最好列求和的函数实现 */
    {my_c_sum1, COL, "循环展开"},
  /* 第二项,应当是你写的最好行列求和的函数实现 */
    {my_rc_sum2, ROWCOL, "循环展开"},

 /* 下面的代码不能修改或者删除!!表明数组列表结束 */
    {NULL,ROWCOL,NULL}
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值