一个绝对注意不到的小细节(深入理解计算机系统第五章5.5及5.6)

来源:互联网 发布:手机oa软件 编辑:程序博客网 时间:2024/05/17 15:56
   下面的计算计算多项式的两种不同方法,形如 a0+a1x+a2x^2········ 

   第二个函数是根据horner法,通过反复提出幂,来减少乘法的次数,按照道理说,既然polyh函数比poly函数减少了乘法的次数,那应该比poly快才对,可是事实正好相反,polyh比poly慢。这是为什么呢?

   如果不深究真的很难发现,想了好久才有了点眉目,首先,CPU加法器和乘法器是完全流水线化的,也就是说可以做到指令级并行(可以把乘法器看成是一条生产线,cpu把一条乘法语句的计算分为若干步骤,像过关一样,第一条乘法语句过了第一关,第二条乘法指令就可以去过第一关了,就像工厂的流水线生产一样),那么一条乘法语句和两条乘法语句是没有区别的。然后再看计算方式,poly函数中的result只跟a[i]*xpwr的结果有关,polyh函数中的result跟a[i]+x*result的结果有关,换成汇编,前者可能只需要两条乘法指令(两条可以并行)一条传送指令就够了,但是后者却需要一条乘法指令一条加法指令(且无法并行,因为加法指令依赖于前面的乘法指令)和一条传送指令,那么想当然执行一条乘法指令的时间要比执行一条乘法指令和一条加法指令的时间短。总结的说一下就是poly函数中计算之间的相关性比较小,而polyh中计算之间的相关性大,就造成了这种意想不到的结果。

double poly(double a[],double x,int degree){       long int i;double result = a[0];double xpwr = x;for(i=1;i<=degree;i++){result+=a[i]*xpwr;xpwr=x*xpwr}return result;}double polyh(double a[],double x, int degree){long int i;double result = a[degree];for(i=degree-1;i>=0;i--)result=a[i]+x*result;return result;}


0 0