字體:小 中 大 | |
|
|
2020/10/06 19:31:05瀏覽5854|回應0|推薦0 | |
第 6 章 主記憶體 主記憶體(primary memory)儲存的資訊是直接交給CPU 使用的,主記憶體的效能遠高於次記憶體,但是次記憶體的容量遠大於主記憶體,對於應用程式來說,最好要用到的資訊(包括程式與資料)都隨時在主記憶體中,這樣用起來才方便,當資料在主記憶體中被更改以後,則要在次記憶體進行對應的更新,這些工作的正常進行都需要作業系統的幫忙。 在這個使用者程式的處理過程中,電腦的記憶體扮演著很重要的角色,作業系統必須知道有多少記憶體空間、要如何分配、每個執行中的程式使用記憶體的狀況,以及重要的資料位於記憶體中的什麼地方, 聽起來就蠻複雜的,所以對於作業系統來說是相當重要而繁複的工作。 記憶體(memory)是電腦中僅次於 CPU 的重要組成,執行程式常用的記憶體可以分成實體記憶體(physical memory)、虛擬記憶體(virtual memory)與快取記憶體(cache)三大類。基本上記憶體可以儲存指令與資料。 作業系統在設計上選擇讓多個處理元分享CPU,這樣的好處是增加CPU 的使用率,另一方面則是提昇電腦對於使用者的回應速度。由於處理元執行時必須位於記憶體中,這表示記憶體也由多個處理元共享,而作業系統則需要有管理記憶體的策略。 主記憶體(main memory)是程式執行時儲存指令與資料的地方,由於應用程式的規模越來越大,對於記憶體的需求也大幅地提昇;在組裝電腦時,我們可以依照自己的需要來決定所選購的記憶體種類及大小, 選購主記憶體時要注意: 1. 主機板的特性︰包括擴充槽的數目及長度,以決定選購的記憶體數目與種類。 2. 記憶體的性能︰包括記憶體的資料存取速率與容量,容量高的記憶體可以減少擴充槽的使用,未來才有繼續增加記憶體的空間。 記憶體最基本的分類是揮發性記憶體(volatile memory)與非揮發性記憶體 (nonvolatile memory)兩大類。電腦關機以後揮發性記憶體中的資料會消失,但是非揮發性記憶體中的資料依然存在,唯讀記憶體(ROM, read only memory)屬於非揮發性記憶體,裡頭儲存了電腦啟動時所需要的資料,一般PC 的ROM 主要用來儲存BIOS(basic input/output system),有點像一個小型的作業系統,在電腦開機時擔當大任。 主機板上有各種記憶體晶片,像唯讀記憶體、快取記憶體(Cache Memory)和隨機存取記憶體(RAM, Random Access Memory)等。通常需要特別採購和安裝的是RAM,個人電腦(即一般Intel-based 或是所謂IBM 相容的PC)所用的RAM 和麥金塔電腦所用的不同。SIMM(single inline memory modules)與 DIMM(dual inline memory modules)是指記憶體晶片的封裝方法,SIMM 有30 pin、72 pin 與144 pin 等,DIMM 有168 pin、172 pin、184 pin 與200 pin 等。另外還有一種RIMM(Rambus inline memory modules),有184 pin 與232 pin 等。 處理器與記憶體之間的連結,為了提昇資料傳送的效率,這部分的連結可以平行傳送多個位元,所謂的連結通常也稱為匯流排(bus)。匯流排的大小代表單一操作能夠傳送的資料大小,記憶體空間一般會以N 個位元為單位分成一個一個的方塊(block),成為字(word),每個word 要有一個在實體記憶體中的位址。 word 有了位址之後就可以透過該位址來進行存取,那麼word 應該多大呢? 通常word 的大小應該要能容納常用的資料類型與指令,一旦選定了word 的大小,電腦系統的組成就要以此大小來協調各單元之間的資料交換,所以常聽到人說32-bit 的電腦系統或是64-bit 的電腦系統,指的就是word size。 記憶體的速度跟CPU 比起來還是太慢,所以跟CPU 搭配工作的還有所謂的快取記憶體(Cache Memory),一般說來,L1 快取記憶體 (primary cache)位於CPU 晶片內,L2 快取記憶體(secondary cache)在獨立的印刷電路版上。L3 cache 也是一種快取記憶體,內建於記憶體中,儲存空間大小是L1< L2<L3 一般說來,資料庫需要的儲存容量多半會超過主記憶體所能容納的空間,而且以儲存的穩定性來說,次要的儲存媒體優於主要的儲存媒體,因此次要的儲存媒體是資料庫主要的儲存場所,當資料需要被使用時才載入到主要的儲存媒體。 記憶體的技術規格有兩個最重要的特徵: 儲存密度(density)與工作頻率,儲存密度是指矽晶片單位面積內記憶單位的數目,不過現在大家都習慣以記憶體晶片的儲存容量來描述這一部分的特徵,例如2G 的記憶體,或是512 MB 的記憶體。 當系統對記憶體進行存取時,從操作開始到結束所花的時間稱為操作延遲時間(latency),不過在實務上兩個操作之間會有間隔,無法避免,所以不能光以執行一個操作所花的時間來衡量記憶體的效能,必須以執行連續的操作所花的時間來度量,所以有記憶體運作時脈(memory cycle time)的概念。 記憶體的技術規格可以從運作時脈、顆粒規格與資料頻寬來觀察。記憶體的資料頻寬可以由工作頻率與資料寬度來計算,以DDR 500 的記憶體為例: 記憶體工作頻率=500 MHz 則資料頻寬=(8 bytes)*500 MHz=4000 MB/s 所以DDR 500 有時候在市場上會標示為PC 4000。 電腦中所使用的資料都儲存在記憶體(memory)中,次記憶體(secondary memory)儲存資料的時間較長,通常位於儲存設備(storage device)上,主記憶 體(primary memory)只載入與程式執行相關的資料暫存,一旦程式結束或不再需要該筆資料,主記憶體會儘快把資料移出。 次記憶體的存取機制和儲存設備以及驅動程式有關,存取的時間通常以 microseconds 為單位,即 10-6秒,比執行用記憶體的存取要來得慢很多。一般說 來,執行用記憶體講求效率,次記憶體強調空間與長期保存。 次記憶體同樣需要管理,一般通稱的記憶體管理程式負責執行用記憶體的配 置(allocation),以及資料在記憶體架構(memory hierarchy)各層級之間的交換。 虛擬記憶體系統(virtual memory system)負責主記憶體與次記憶體之間、以及快取記憶體與主記憶體之間資料的自動轉移。檔案管理程式(file manager)則負責次記憶體空間的管理。所以談到電腦系統中記憶體的管理,都會談到執行用記憶體的管理、虛擬記體的觀念與技術,以及檔案的管理,這是在學習記憶體的管理時一定要先建立的觀念。 記憶體管理程式的主要功能如下 : 1. 將主記憶體空間分配給處理元。 2. 協調處理元位址空間(address space) 與主記憶體之間的對應關係 (mappings) 。 3. 在現有的主記憶體容量下縮短存取時間。 記憶體可以看成是由一連串的位元組(byte)所組成,每一個位元組都有一個特定的位址(address)。CPU依據程式計數器(program counter)中的值從記憶體中取得指令來執行,指令執行的過程中可能導致資料從記憶體載入(load)、或是資料儲存(store)到記憶體中。 程式指令執行的過程中會先從記憶體中取得指令,然後進行解譯(decode),這時候可能需要從記憶體取得運算元(operand),也就是運算的資料。運算完成時也可能需要將結果儲存到記憶體中。 內建於CPU中的主記憶體與暫存器是CPU可以直接存取的儲存空間,機器語言寫的指令可以將記憶體位址當成參數(argument),但是無法直接使用磁碟位址(disk address)。CPU內的暫存器的存取時間約為CPU時鐘1個週期的時間,而同樣的時間內CPU能夠處理1到數個指令。 處理元在記憶體中的分佈狀況,通常會運用硬體的方法來防止使用者的執行處理元存取作業系統分佈的區域,同時也要確保處理元彼此之間不會存取其他處理元使用的儲存空間。 在實務上CPU硬體在記憶體存取操作進行時會比較產生的位址與暫存器中儲存的值,必須確認「(value in base register)=< memory address< (value in base register + value in limit register)」,才能進行存取,否則就要踏入作業系統的陷阱(trap),產生系統錯誤。 CPU所產生的記憶體位址通常稱為「邏輯位址(logical address)」,而管理記憶體的記憶體單元(memory unit)所看到的則是所謂的「實體位址(physical address)」,載入到「記憶體位址暫存器(memory-address register)」的是實體位址。儲存在磁碟上的可執行程式的格式通常是二元的可執行檔案格式(binary executable file),執行的時候可執行程式會以處理元的型式儲存於記憶體中。 下面以一段程式碼來說明程式處理的方式,要了解的問題是程式或資料的位址最後如何對應到實體的位址: static int globalVar; …… int procedure_A(int arg1) { …… globalVar=15; store_record(globalVar); …… } 以靜態變數(static variable)來說,在編譯時期compiler就會產生分配儲存空間的程式碼,通常所配置的空間會在程式的資料區段(program data segment),以一般的變數來說,將位於執行時期的堆疊(runtime stack)上,以程序的啟始點(procedure entry point)而言,compiler無法決定其位址,因為程序可能位於另一個可重定位的模組(relocatable module)內,必須等到連結時期(link time)才能處理,編譯的時候會先把引用到這些程序的位址以外來位址來代表,等連結(link)的時候再放入正確的位址。 在連結時期,compiler產生的各資料區段會合併成單一的資料區段,指令引用到這些資料區段的部分要重定位,使他們指向絕對模組(absolute module)中的正確位置。至於程式指令中引用到這些資料區段的位址都要重定位成新的位址,而程序的啟始點現在也明朗了,因此原先的外來位址同樣需要重定位成新的位址。所謂新的位址現在是指絕對模組(absolute module)中的位址。 載入時期中,位址必須再度調整,原本絕對模組的位址是假設載入的實體位址為0,實際載入時可能在其他的位址,因此一旦載入程式(loader)確定了載入的實體位址,將會對實體位址與程式位址進行連結(bind)。 假如heap storage不夠用的話,malloc會使用sbrk呼叫核心記憶體管理程式,要求系統分配更多記憶體空間給處理元,這時候處理元的位址空間必須與主記憶體空間再連結(rebind),使原先程式裡對記憶體空間的引用能繼續有效。至於這是怎麼做到的就和作業系統實作的細節有關了。 記憶體管理程式必須把記憶體空間有效地分配給所有的處理元共用,分配的方式可以分成兩大類 : 1. 在作業系統的組態設定中就將主記憶體空間分割成固定數目固定大小的方塊。這就是前面曾經介紹的靜態的固定分割的方式。 2. 使用動態決定而且大小不一的(variable-sized)方塊來配置。我們盡量分配剛好符合需求的記憶體空間給處理元使用。 記憶體的配置必須克服空間散佈(fragmentation)的問題,空間散佈會降低記憶體空間的使用效率,固定大小的配置方法會造成內部的空間散佈(internal fragmentation),因為分配給處理元的空間都是固定大小的,而且大於實際的需求。假如預先知道處理元所需要的記憶體空間大小,可以降低內部的空間散佈問題,但是對於分時系統來講,這是無法做到的,因為無法預知所需的空間大小。 變動大小的配置方式依照處理元的需求來分配記憶體空間,內部的空間散佈比較不嚴重,記憶體管理程式必須監控變動大小的記憶體方塊,這種配置方式會造成所謂的外部的空間散佈(external fragmentation)問題,空間配置的策略: 1. 最佳配置(best fit) : 把跟需求大小最接近的記憶體區塊分配給處理元。 2. 最糟配置(worst fit) : 把最大的記憶體區塊分配給處理元。如此一來,可能剩下來的空間更容易再分配出去。 3. 最先配置(first fit) : 以第一個找到的夠大的記憶體區塊分配給處理元。節省尋找的時間。 4. 下一個配置(next fit) : 最先配置容易在靠起頭的位置造成外部的空間散佈,每次配置完之後,下一次的配置從前一次的配置位址往後找,避免外部的空間散佈集中在一起。 程式執行時會分配到記憶體空間,但是萬一執行過程中程式位置需要改變,會產生什麼情況呢? 有幾個重要的觀念需要澄清: 1. 載入程式(loader)只能針對絕對模組(absolute module)重定位,無法對執行映像(executable image)做類似的處理。 2. 絕對模組具有特殊的格式,包括了compiler與linkage editor留下來的一些旗標(flags) ,載入程式產生執行映像時會移除這些旗標。 動態位址重定位(dynamic address relocation) 原始程式中的符號最先會連結到compiler產生的可重定位模組(relocatable module)裡的相對位址(relative address),link時則連結到絕對模組(absolute module)裡的位址,載入時則連結到真正的記憶體位址(memory address)。連結到指定的資料結構。假如執行時期有辦法重新連結(bind)程式使用的位址,則記憶體管理程式將能輕易地移動記憶體中的程式。這種功能叫做動態位址重定位(dynamic address relocation)。 把記憶體分割以後便於支援多工的(multiprogramming)作業,但是占有記憶體的處理元有可能在某些原因下暫停(blocked)執行,假如此時有其他的處理元需要記憶體空間繼續執行,則我們可以考慮把暫停的處理元移出主記憶體,讓其他的處理元能得到記憶體的資源。這是交換作業(swapping)的由來。 交換作業記憶體管理程式(swapping memory manager)負責把暫停的(blocked) 處理元移出主記憶體,把空出來的記憶體空間配置給其他的處理元。當原來被暫停的處理元可以恢復執行時,記憶體管理程式必須再配置適當的記憶體給恢復執行的處理元。 在處理元移出(swap out)與移入(swap in)的過程中,會有位址連結(address binding)的問題,假如使用硬體重定位的方法會比較單純,再移入時只要把可執行的映像(executable image)拷貝到主記憶體內即可。在分時(timesharing)系統中,交換作業可以讓少有活動的使用者處理元暫時移出,比較活躍的使用者處理元則獲得記憶體空間來進行各種請求。因此,對於分時系統來說,即使處理元不是在暫停的狀態,記憶體管理程式還是可以將處理元移出,端視目前處理元的活動情況與系統的資源使用情形而定。有幾個和交換作業相關的觀念有必要加以釐清: 1. 假如沒有任何被記憶體管理程式暫停的處理元,則沒有交換的必要。 2. 一旦交換作業開始發生,通常系統的回應會變慢。 |
|
( 知識學習|隨堂筆記 ) |