深入理解計算機系統系列02

2021-09-22 19:56:00 字數 1368 閱讀 9116

深入理解計算機系列02

在《深入理解計算機系統》這本書中,提出了加法逆元的思想,並且輔以乙個習題,我們知道兩數交換的最經典的演算法是三數交換,從計算機的底層實現上看,記憶體與暫存器之間的錯位交換已經是兩數交換的最快演算法了,這本書的習題也提到,上面寫出的加法逆元的兩數交換的演算法本質上並沒有實現出更快的兩數交換,而是一種智力題。下附**:

對於任一位向量,有a^a=0

void inplace_swap()(int *x,int *y)

設「+」為乙個交換性的二元運算,即對於所有x,y,x+y=y+x。若該集內存在乙個元素0,使得對於所有x,x+0=0+x=x,則此元素是唯一的。如果對於乙個給定的x,存在乙個x』使得x+x』=x』+x=0,則稱x』是x的加法逆元。

所以說,這其實是乙個廣義的加法逆元的說法,這裡我們的每乙個元素就是它自身的加法逆元。

之後更有意思的是,《深入理解計算機系統》習題2.10之後又附加了乙個2.11題,使用習題2.10的函式實現將乙個陣列中的元素頭尾兩端依次對調,下為**

void reverse_array(int a,int cut)

然後提出了乙個問題,上述的**只在陣列長度為偶數的時候正確工作,而在奇數的情況下只會將中間的**設定為0。然後讓我們解釋一下是為什麼。

這裡就出現了乙個十分有趣的事情,從明面上看,我們下面的**好像一點沒錯,可為什麼會出錯了那?

仔細一看是這樣,下面的**並沒有錯,但是上面的兩數交換的**出了錯,它只考慮了一般的情況(即兩數不相等的情況),而兩個數相等的兩數交換它並沒有考慮,實際上,由於在上面的兩數交換演算法中如果兩數相等,在中間的乙個步驟中,會產生乙個0,而又因為,這兩個數其實是乙個數,用乙個記憶體空間,就都成了0

這提示了我們,1.**的出錯不一定是這個**本身的出錯,還有可能是引用的別的**處理了錯

2.一定要考慮極端情況,這點在acm中表現的尤為明顯。

那麼書中提問了解決辦法,在不改變上面的交換演算法的情況下,如何改變下面的**使得該**在奇數的時候正常工作那?

簡單的想想就會有兩種方法

1.不改變中間的值,即為把for迴圈的判斷<=改為《符號,這樣就不會對中間的數做修改

2.先將中間的數儲存起來,然後再將中間的數賦值過去

這麼簡單的乙個題,卻又有著兩種方法,體現了兩種思想,一種是不做修改,一種是做兩次修改,改完之後再改回來

這個東西十分有趣,給了我們一些很重要的啟發

最後附上兩數交換的另一種演算法(可讀性不太好)

1: void swap(int *a, int *b)

2:

這種兩數交換的實現方式也十分有趣,能夠充分體現運算子優先順序的巨大用處,十分巧妙。

深入理解計算機系統系列05

大多數編譯器提供編譯器驅動程式,它代表使用者在需要的時候呼叫語言處理器,編譯器,彙編器,和鏈結器。它將main.c翻譯成為乙個ascii碼檔案的中間檔案main.i,之後驅動編譯器翻譯器將其翻譯成乙個ascii組合語言檔案,main.s,之後驅動彙編器再將其翻譯成為乙個可重定位的目標檔案main.o...

深入理解計算機系統

關鍵路徑是在迴圈的反覆執行中形成的資料相關鏈。迴圈展開是一種程式變換,通過增加每次迭代計算的元素的數量,減少迴圈的迭代次數。重新結合變換能夠減少計算中關鍵路徑上操作的數量,通過更好地利用功能單元的流水線能力得到更好的效能。浮點運算不保證是可結合的,通常迴圈展開和並行地累積在多個值中,是提高程式效能的...

《深入理解計算機系統》

知乎 深入理解計算機系統 這本書需要什麼水平能看懂?15 213 18 218 15 513 introduction to computer systems schedule fall 2016 鏈結失效則 cmu15 213的課程主頁,有ppt,還有錄影,主講人就是這本書的作者。備註 備註 詳細...