妨碍优化的因素

今天在看《深入理解计算机系统》时看到了性能优化,认识到了之前从未考虑过的问题。

妨碍优化的因素:

1.计算依赖的指针p和q 是否指向存储器中同一个位置

2.函数调用

举例说明:

1)

void twiddle1(int *xp,int *yp){
	*xp+=*yp;
	*xp+=*yp;
}

void twiddle2(int *xp,int *yp){
	*xp+= 2 * *yp;
}

乍一看,这两个过程似乎有相同的行为,他们都是将存储在由指针yp 指示的位置处的两次加到指针xp指示的位置处的值。另一方面,函数twiddle2函数效率更高一些。它只要求3次存储器引用(读*xp,读*yp,写*xp)而twiddle1需要6次(2次读*xp,2次读*yp,2次写*xp)。因此,如果要编译器编译过程twiddle1,我们会认为基于twiddle2执行的计算能产生更有效的代码。

不过,考虑xp等于yp的情况,此时,函数twiddle1会执行下面的计算:

*xp += *xp;
*xp += *xp;

结果是xp的值会增加4倍。另一方面,函数twiddle2会执行下面的计算:

*xp += 2 * *xp;

结果是xp的值会增加3倍。编译器不知道twiddle1会如何被调用,因此它必须假设参数xp 和yp可能会相等。因此,它不能产生twiddle2风格的代码作为twiddle1的优化版本。

2)

int f();

int func1(){
    return f()+f()+f()+f();
}

int func2(){
    return 4*f();
}

最初看上去两个过程计算的都是相同的结果,但是func2只调用了f 1次,而func1调用了4次。以func1作为源时,会很想产生func2风格的代码,不过,考虑下面f的代码;

int counter=0;

int f(){
    return conter++;
}

这个函数有个副作用,它修改了全局程序状态的一部分。改变了调用它的次数会改变程序的行为。特别的,假设开始时全局变量counter 都设置为0,对 func1的调用会返回 0+1+2+3=6 ,而func2的调用会返回4*0=0.

你可能感兴趣的:(C)