一個絕對注意不到的小細節(深入理解計算機系統第五章5.5及5.6)
阿新 • • 發佈:2019-02-06
下面的計算計算多項式的兩種不同方法,形如 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;}