perflab1

一、首先对于函数1:naive_rotate(幼稚的翻转!?)

void naive_rotate(int dim, pixel *src, pixel *dst) 
{
    int i, j;

    for (i = 0; i < dim; i++)
	for (j = 0; j < dim; j++)
	    dst[RIDX(dim-1-j, i, dim)] = src[RIDX(i, j, dim)];//一位数组模拟二维矩阵,RIDX为宏定义(i*dim+j) 
}

1、优化1:

先看以下代码:

#include <iostream>
#include <ctime>
#define maxn 10000
using namespace std;
int test[maxn][maxn];
int main()
{
	int tot=0;
	clock_t st,en;
	
	st=clock();
	for(int j=0;j<maxn;j++)
	{
		for(int i=0;i<maxn;i++)tot=test[i][j];
	}
	en=clock();
	cout<<en-st<<"ms\n";
	
	st=clock();
	for(int i=0;i<maxn;i++)
	{
		for(int j=0;j<maxn;j++)tot=test[i][j];
	}
	en=clock();
	cout<<en-st<<"ms";
	
} 

运行结果如下:

内外循环次序的改变导致时间的不同,根本在于寻址时间的差异。

对于rotate函数的语句:dst[RIDX(dim-1-j, i, dim)] = src[RIDX(i, j, dim)];

其中等号前相当于写入地址,等号后相当于从地址中读。我们因尽量优化写的寻址,因此交换循环次序:

void attemp2(int dim, pixel *src, pixel *dst)
{
	int i,j,mid;
	for (j = 0; j < dim; j++)
    for (i = 0; i < dim; i++)
	    dst[RIDX(dim-1-j, i, dim)] = src[RIDX(i, j, dim)];
}

2、优化2:

先了解循环展开,戳这->https://www.baidu.com/link?url=0wLJxEzROLGsUMr8ZQqMSJ4aDn6KCO0bZO6R9-r0Sjx0NAqI6eGp5v8SZv9e9kkNKCOAVcWOCLZBTFF7UaHSZFPhryn869ftK_8gSOzAb5S&wd=&eqid=e13f913a002f1e12000000065ca97278

因为测试样例全为32的倍数,因此可做4,8,16...的展开:

需要添加的语句分别为4*4,8*8,16*16

void attemp3(int dim, pixel *src, pixel *dst)
{
	int i,j,mid;
	//j对应外层循环展开,i对应内层循环展开 
	for (j = 0; j < dim; j++)
    {
    	for (i = 0; i < dim; i+=4)
	    {
		    dst[RIDX(dim-1-j, i, dim)] = src[RIDX(i, j, dim)];
		    dst[RIDX(dim-1-j, i+1, dim)] = src[RIDX(i+1, j, dim)];
		    dst[RIDX(dim-1-j, i+2, dim)] = src[RIDX(i+2, j, dim)];
		    dst[RIDX(dim-1-j, i+3, dim)] = src[RIDX(i+3, j, dim)];
		    
		    
		    dst[RIDX(dim-1-j-1, i, dim)] = src[RIDX(i, j+1, dim)];
		    dst[RIDX(dim-1-j-1, i+1, dim)] = src[RIDX(i+1, j+1, dim)];
		    dst[RIDX(dim-1-j-1, i+2, dim)] = src[RIDX(i+2, j+1, dim)];
		    dst[RIDX(dim-1-j-1, i+3, dim)] = src[RIDX(i+3, j+1, dim)];
	       
	    
	       
		    dst[RIDX(dim-1-j-2, i, dim)] = src[RIDX(i, j+2, dim)];
		    dst[RIDX(dim-1-j-2, i+1, dim)] = src[RIDX(i+1, j+2, dim)];
		    dst[RIDX(dim-1-j-2, i+2, dim)] = src[RIDX(i+2, j+2, dim)];
		    dst[RIDX(dim-1-j-2, i+3, dim)] = src[RIDX(i+3, j+2, dim)];
    
    	
		    dst[RIDX(dim-1-j-3, i, dim)] = src[RIDX(i, j+3, dim)];
		    dst[RIDX(dim-1-j-3, i+1, dim)] = src[RIDX(i+1, j+3, dim)];
		    dst[RIDX(dim-1-j-3, i+2, dim)] = src[RIDX(i+2, j+3, dim)];
		    dst[RIDX(dim-1-j-3, i+3, dim)] = src[RIDX(i+3, j+3, dim)];
	    }   
	}
}

3、优化3:

循环的分块(简直就是个黑科技)

基本想法如下:若进行10000*10000二重循环的计算那么可以将将10000*10000的二重循环拆分成1000*1000个的10*10的二重循环这时分块的大小为10,或者拆成若干个5*5的二重循环,这时分块的大小为5。分块大小的不同将显著影响程序的运行速度(具体涉及深层的计算机原理,现在就当个STL样的东西用就好了,哈哈)

可见以下代码:

#include <iostream>
#include <ctime>
#define maxn 10000
using namespace std;
int map[maxn][maxn];
int main()
{
    int tot=0;
    
    clock_t st,en;
    st=clock();
    for(int i=0;i<maxn;i++)
    {
    	for(int j=0;j<maxn;j++)
    	map[i][j];
	}
	en=clock();
	cout<<en-st<<"ms\n";
	tot=0;
	
	st=clock();
	int blocksize=5;
	for(int i=0;i<maxn;i+=blocksize)
	  for(int j=0;j<maxn;j+=blocksize)
	  {
	  	
	  	 for(int jj=j;jj<j+blocksize;jj++)
	  	 for(int ii=i;ii<i+blocksize;ii++)
	  	   map[ii][jj];
	  }
	en=clock();
	cout<<en-st<<"ms\n";
} 

于是得到优化3的代码:

void attemp4(int dim, pixel *src, pixel *dst)
{
    int i,j,ii,jj,mid,blocksize=32;//因为样例为32的倍数,所以块的大小可分为(32*k)*(32*k) 
    
    //注意一下四个循环的次序,进行调换会显著影响时间 
    for(i=0;i<dim;i+=blocksize)
	for(j=0;j<dim;j+=blocksize)
	  {
         for(jj=j;jj<j+blocksize;jj++)
	     for(ii=i;ii<i+blocksize;ii++)
	  	 dst[RIDX(dim-1-jj, ii, dim)] = src[RIDX(ii, jj, dim)];
	  }
	  
}

待更。。。

----------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

 

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值