- 記憶體層次結構和資料結構的設計在很大程度上決定了 CPU 快取的使用率。
- 將熱點資料分組、使用連續容器和 SoA 模式可以減少快取未命中並改善延遲。
- 在 Windows 系統中,更新系統和驅動程式並限制後台程序可以釋放 CPU、RAM 和快取。
- 透過軟體優化、電源調整以及必要時的硬體改進,可以最大限度地提高整體性能。
CPU快取優化是區分「能運行」程式碼和「運行流暢」程式碼的關鍵所在。當我們理解記憶體的組織方式、每一級快取的存取時間以及硬體的運作機制時,無需更換機器就能大幅提升效能。
同時,相當一部分 Windows 用戶正面臨一個更為常見的問題:電腦運作緩慢。而問題的根源往往就在於此,也就是記憶體、快取和 CPU 本身的低效率利用。透過合理的底層設計(資料結構、記憶體存取模式)以及Windows 系統中的實用調整(清理、更新、電源模式等),可以顯著提升電腦效能,提升幅度從 5% 到某些情況的 30-40% 不等。
記憶體層次結構與延遲:快取規則的重要性
在開始修改程式碼或配置 Windows 之前,必須先理解一點:並非所有記憶體都一樣。存取 L1、L2、L3 快取、RAM 或磁碟之間的差異巨大,許多快取優化方案的核心就在於盡可能避免存取速度較慢的快取層級。
在現代處理器中,典型的存取時間(數量級)大致如下:存取L1 快取大約需要半納秒,分支預測未命中需要幾納秒,L2快取大約需要 7 奈秒,而存取主記憶體則可能超過 100 奈秒。如果我們將存取範圍擴展到電腦之外(例如網路、固態硬碟、機械硬碟),這些數字將飆升至數十萬甚至數百萬奈秒。
這種顯著差異正是資料組織、減少快取未命中和設計順序存取模式如此重要的原因。即使在邏輯上執行相同的功能,駐留在 L1 快取中的循環也比不斷存取 RAM 或 SSD 的循環快得多。
此外,CPU快取分為多個等級:L1快取容量很小,速度極快;L2快取容量稍大,速度稍慢;L3快取容量更大,通常由多個核心共享。其理念是將存取頻率最高的資料(「熱資料」)放在觸手可及的位置,而將其他資料放到速度較慢的層級。作為開發者,我們可以透過良好的資料結構設計和可預測的存取方式,自然而然地實現這一點。
什麼是緩存?為什麼它會影響性能?
在任何場景下(CPU、磁碟、網路等),快取都是對最近使用資料的快速儲存。我們無需總是存取速度最慢的資料來源,而是保留一份最有可能被重複使用的資料副本。這縮短了反應時間,並減輕了對主資源的壓力。
一般來說,快取用於加快存取速度並改善用戶體驗。實際上,它還能讓系統在相同的硬體條件下執行更多工作:減少等待時間、減少阻塞、減少佇列。因此,它被廣泛應用於 CPU、磁碟、瀏覽器、分散式系統以及幾乎所有資料密集型軟體中。
一台典型的PC有幾種類型的快取:磁碟快取(用於儲存硬碟資料的RAM)、Web快取(靜態瀏覽器資源)和CPU快取(L1、L2、L3)。它們的工作原理基本上相同:儲存以後可能需要的數據,避免重複執行耗時的操作。
快取類型:磁碟快取、Web快取和CPU緩存
在實際系統中,多種快取機制相互交匯,各自發揮不同的功能。理解這些機制有助於更好地進行編程,也有助於診斷電腦效能低於預期的原因。
磁盤緩存
磁碟快取是記憶體(通常是 RAM)中的一塊區域,作業系統會將最近從磁碟讀取或寫入的資料儲存在其中。當應用程式再次要求這些資料時,系統首先會檢查快取:如果資料在快取中,則存取速度比存取磁碟快得多,尤其是在使用機械硬碟時。
這種機制能夠顯著縮短載入時間,減少物理讀寫操作次數,進而延長磁碟壽命。在需要重複存取相同檔案的場景(例如資料庫、伺服器、資源密集型應用程式)中,磁碟快取能夠帶來顯著的效能提升。
Web 快取
瀏覽器中的網頁快取會暫時儲存圖片、樣式表、JavaScript 和其他資源。這樣,當您再次訪問某個頁面或在同一網站的不同版塊之間導航時,瀏覽器就可以直接訪問已存儲的信息,而無需再次從網絡請求。
這樣做有兩個好處:一是用戶載入時間更短,二是用戶網路連線和伺服器頻寬消耗都更低。但是,如果快取管理不當,可能會出現過時的資源,因此有時建議清除快取。
CPU快取:L1、L2和L3級
就效能而言,CPU快取是至關重要的組成部分。現代處理器包含多個層級的緩存,旨在最大限度地減少資料和指令存取延遲。一般來說,L1快取最小且速度最快,L2快取速度居中,L3快取最大且速度最慢,通常與其他快取共享。
一級快取(L1快取)通常分為指令段和資料段,每個核心的典型大小為幾十KB。它速度極快,用於立即處理資料。二級快取(L2快取)容量更大(幾百KB到幾MB),作為一級快取的備份。三級快取(L3快取)容量可達數MB甚至數十MB,由多個核心共享,是存取RAM之前的最後一級快取。
當記憶體存取模式相對有序或可預測時,硬體可以預先判斷並將資料載入到對應的快取層級。但如果存取模式混亂,充滿隨機跳轉和分散的結構,處理器就會花費過多時間等待內存,導致CPU「閒置」。這時就需要進行程式碼級優化了。
優化資料結構以進行 CPU 緩存
效能很大程度取決於我們如何設計資料結構。將一個包含冷熱字段的大型物件與將常用字段和不常用字段分開是截然不同的。每個被送至處理器的快取行都會產生開銷;如果我們用無用資料填充這些快取行,就會浪費頻寬。
分組熱數據並分離冷數據
關鍵策略在於識別結構體中哪些欄位幾乎每次操作都會存取(「熱」資料),哪些欄位僅偶爾使用(「冷」資料)。前者應集中儲存在記憶體中,並儘可能放入一個或幾個快取行。後者可以儲存在單獨的結構體中,並透過指標或索引進行引用。
例如,與其建立一個包含冗長字串(姓名、簡介、郵箱)並混雜著需要不斷檢查的標誌或標記的使用者對象,不如將「熱門」資料(ID、上次登入時間、活躍狀態)分組到一個緊湊的結構中,並將其餘資訊放在一個單獨的「詳細資料」結構中。這樣,當程式碼遍歷使用者清單以檢查狀態或標記時,快取行幾乎完全被相關資料填充。
減少冗餘,更好地利用每條線
另一個戰場在於結構的物理設計:欄位的順序和類型。由於對齊問題,隨意混合不同大小的資料類型會導致填充字節的出現,這些填充字節只會浪費內存,更糟的是,還會佔用快取行。
如果我們重新排列資料結構,先放置大類型資料(例如 double 或 int64_t),再放置中等類型數據,最後放置最小類型資料(例如 bool、char),通常可以減少或消除大部分填充資料。這樣,每個快取行可以容納更多元素,從而減輕記憶體層次結構的壓力,並降低記憶體未命中的可能性。
選擇相鄰的容器
將元素儲存在連續記憶體中的容器(例如向量)通常比基於稀疏節點並透過指標連結的結構(例如樹、經典鍊錶等)更利於快取利用。遍歷向量時,硬體可以完美預測下一次訪問,並預先載入後續的快取行。
相較之下,像基於樹的映射或鍊錶這樣的結構會將節點分佈在堆記憶體中,迫使 CPU 持續進行指標追蹤。每次指標跳躍都可能導致快取未命中,並產生代價高昂的返回主記憶體的開銷。這就是為什麼許多現代庫提供密集哈希映射、開放表和其他容器來盡可能保持資料緊湊的原因。
小型收藏品的線上存儲
許多演算法涉及非常小的集合(幾個整數,幾個結構體),這些集合會不斷地被創建和銷毀。如果每次建立和銷毀集合都觸發堆記憶體分配,不僅會增加記憶體管理成本,還會導致資料分散在記憶體中。解決方案是使用具有線上儲存的容器來儲存小規模資料。
這種類型的容器會在物件內部直接預留 8 或 16 個元素的空間。只要不超過這個限制,就不需要存取堆內存,資料會一直與函數或類別的其他狀態關聯,這對於快取非常有利。
存取模式:從 AoS 到 SoA 以及位元集的使用
即使快取結構良好,資料存取模式也很大程度上決定了效能。順序遍歷數組和基於指標列表從一個位址跳到另一個位址是截然不同的。有一些常用的技巧可以最大限度地利用快取。
結構數組 (AoS) 與數組結構 (SoA)
一個經典的模式是從「結構體數組」(AoS)設計到「結構體數組」(SoA)設計的轉變。在AoS中,每個元素都是一個包含多個欄位的物件(例如,粒子的位置和品質),這些元素按順序儲存。當您只需要讀取其中的一部分欄位(例如,位置)時,您就必須載入包含未使用資料的快取行。
另一方面,在SoA架構中,不同的屬性被分離到平行數組中:一個用於x座標,一個用於y座標,一個用於z座標,一個用於質量,以此類推。因此,如果演算法僅更新位置,則它只會存取座標數組,快取不會被無關資訊污染。此外,這種設計有利於向量化和SIMD指令的使用。
位元集和按索引引用
對於小型域(例如,標誌位元範圍為 0 到 255),使用位元集比基於雜湊的集合結構效率更高。一個 256 位元的位元集僅佔用幾十字節,並且允許進行非常快速、完全連續且快取友好的操作,而無需在雜湊表中解決衝突。
類似地,在連續數組中用索引替換指標可以減少結構體的大小(使用 32 位元索引取代 64 位元指標),並提高快取一致性。節點不再分散在堆上,而是儲存一個節點向量,並根據其位置進行訪問,從而簡化了順序遍歷。
預取:何時提前完成工作
除了硬體預取(用於預測順序存取模式)之外,我們還有軟體預取指令,用於在特定情況下提前載入資料。當存取模式可預測但並非嚴格線性時,例如雜湊表或鍊錶,軟體預取就顯得尤為重要。
基本想法很簡單:在處理元素 i 時,指示硬體將元素 i+1(或某個未來的資料區塊)載入到快取中。當處理到該元素時,它已在 L1 或 L2 快取中的機率很高,從而減少了等待時間。這可以透過編譯器預取原語或特定函式庫來實現。
然而,對於完全順序的訪問,顯式預取毫無意義,因為硬體已經自動處理了。事實上,增加不必要的預取反而會使快取變得臃腫,降低效能。效能優化通常都需要進行前後對比測試。
快取位置、替換和預取策略
從更理論的層面來說,快取系統是基於一系列策略,這些策略決定了資料儲存的位置、何時檢索數據,以及在空間不足時需要清除哪些資料。雖然這些細節由硬體或作業系統管理,但理解它們有助於解釋某些異常行為。
在記憶體位置方面,可以使用記憶體分段或群組相聯分配方案,其中每個主記憶體位址只能對應到快取的子集。這會影響衝突的數量以及兩個位址在快取中重疊的機率。
關於快取刷新(快取未命中時的處理方式),替換策略就派上了用場:LRU(最近最少使用)、FIFO(先進先出)甚至隨機替換。 LRU 策略會嘗試將最近使用的資料保留在快取中,假設這些資料之後還會再次使用;而 FIFO 策略則會直接丟棄最舊的資料。每種策略都有其自身的優勢,取決於實際的存取模式。
在預取部分,存在一些基於歷史模式的機制:例如,如果硬體偵測到每次存取都會偏移 64 位元組,它就會傾向於預取連續的資料區塊。在其他情況下,則會使用空間預取(即使只要求了一部分,也預取整個資料塊)來最大限度地減少存取主記憶體的次數。
測量和分析快取行為
不進行測量就進行優化,就像盲人摸象。有一些效能分析工具可以讓你查看特定的快取指標:引用次數、L1 快取未命中次數、末級快取 (LLC) 未命中次數、未命中率等等。這些指標可以顯示你的更改是否真的改善了效能。
例如,如果一級快取未命中率在 2% 到 3% 左右,通常被認為是合理的;而極高的末級快取未命中率則可能表示存在空間局部性或時間局部性問題。將這些資料與 CPU 和記憶體使用情況分析相結合,有助於確定程式碼的哪些部分對記憶體層次結構造成了最大的壓力。
Windows 中的快取和效能最佳化
除了程式碼本身,許多用戶都疑惑,為什麼他們的 Windows 電腦運行速度如此緩慢,明明「理論上」擁有不錯的 CPU 和記憶體。部分原因在於作業系統、內建應用程式以及累積的數位垃圾會不斷佔用 CPU、記憶體和緩存,導致留給重要任務的資源減少。透過在 Windows 10 和 Windows 11 中應用一些特定的最佳化措施,可以釋放 CPU 和記憶體資源(例如,透過配置虛擬記憶體),減少後台進程,並提高系統快取相關資料的能力。根據初始情況的不同,這些優化措施的效果可能從細微的調整到顯著提升整體效能不等。
更新 Windows 和驅動程式
很多人忽略的一個非常基本的步驟是保持作業系統和驅動程式的更新。 Windows 更新不僅包含安全性修補程式:它們通常還包括資源管理方面的改進、記憶體洩漏修復和核心最佳化。
在 Windows 設定面板(「開始」>「設定」>「更新與安全性」>「Windows 更新」)中,您可以搜尋常規更新和選用更新包,其中包括可最佳化 CPU、GPU 或晶片組效能的非關鍵驅動程式。安裝這些元件可以解決直接影響快取和記憶體利用率的瓶頸或穩定性問題。
停用 P2P 更新分發
自 Windows 10 起,系統可以透過 P2P 機制與其他電腦下載和共用更新。雖然這種機制很巧妙,但這意味著電腦需要佔用 CPU、網路和磁碟空間來幫助分發更新,這並非總是理想的。
停用 Windows 更新中的「傳遞最佳化」功能,可以阻止您的電腦提供給其他電腦或下載更新片段。這可以釋放資源、減少後台活動,並提高整體效能,尤其是在配置較低的系統上。
釋放磁碟空間並刪除垃圾文件
當硬碟空間不足或接近滿格時,Windows 用於分頁和建立暫存檔案的空間就會減少,最終影響系統效能。使用內建的磁碟清理工具可以刪除臨時檔案、更新殘留檔案、回收站中的項目以及其他不必要的資料。
除了使用清理工具之外,建議定期清空回收站,並使用 Windows 儲存選項刪除累積的暫存檔案。系統磁碟機上的空間越少,記憶體子系統運作效率越高,磁碟快取功能也越有效。
優化啟動和後台程式
對於日常使用的電腦來說,CPU 和快取的最大敵人之一是那些自動啟動並在背景運行的程式:同步程式、更新程式、我們幾乎不使用的小工具等等。雖然它們看起來很輕量級,但每個程式都會增加執行緒、記憶體、磁碟存取和快取消耗。
在任務管理器或使用Sysinternals 監控進程時,您可以在「啟動」標籤中停用不必要的應用程式自動啟動。您還可以在「隱私設定」中控制哪些應用程式允許在背景運行。減少此清單不僅可以縮短啟動時間,還可以降低 CPU 和記憶體的持續負載。
減少圖形效果和通知
視窗動畫、透明效果和其他視覺美化效果都會消耗系統資源。在老舊或配置較低的電腦上,調整 Windows 設定以優先考慮效能而非外觀可能更有益。這可以透過系統進階選項中的「效能」設定來完成,選擇優先考慮速度的配置即可。
同樣,過多的通知會讓用戶和設備不堪重負。停用不必要的提醒不僅可以簡化使用者體驗,還能防止後台進程和檢查過於頻繁地運行。
功率模式、休眠和峰值性能
Windows 內建了多種電源計劃,直接影響 CPU 的管理方式:是優先考慮電池續航時間還是純粹的效能。對於連接電源的桌上型電腦和筆記型電腦,通常最好檢查這些設定。
快速啟動結合了關機和休眠的功能,透過在關機前預先載入部分核心和驅動程式來加快啟動速度。啟用此功能可以顯著縮短啟動時間,但如果它導致更新或 BIOS 存取出現問題,建議暫時停用它。
另一方面,還有一個隱藏的「最高效能」模式,它會強制CPU和其他元件以較低的能源效率標準運作。啟用此模式可以為高強度任務提供更多效能餘裕,但代價是發熱量、風扇噪音和功耗都會增加。
系統中空間和記憶體的高效管理
除了定期清理和控制駐留程式外,還有其他方法可以更好地利用電腦的實體資源,進而更好地利用 CPU 和磁碟快取。
桌面上堆滿圖標、快捷方式、資料夾和文件不僅僅是視覺上的混亂:Windows 系統還需要管理所有這些內容,這會增加額外的工作。保持桌面整潔,並將檔案整理到磁碟機內的資料夾中,這種簡單的做法有助於營造更輕的作業系統環境。
使用雲端儲存解決方案來存放某些文件也有助於減少本地儲存空間的使用。如果操作得當(不完全依賴網路連線),就能減輕本地系統的負擔,並使其更有彈性。
具體技術:ReadyBoost、超頻和硬體
對於配備機械硬碟和有限記憶體的計算機,Windows 系統內建了 ReadyBoost 等技術,可讓您使用高速 USB 隨身碟作為額外的快取。雖然這並非萬能靈藥,但在某些配置下,它可以透過減輕硬碟的部分負擔來提升效能。
另一方面,進階使用者可以使用諸如 Intel Extreme Tuning Utility(適用於未鎖頻處理器)之類的工具對 CPU 進行超頻。提高時脈頻率可以提升效能,但也會增加溫度和功耗,如果電壓和散熱管理不當,則存在系統不穩定甚至損壞的風險。
當所有軟體最佳化都無法解決問題時,就該考慮硬體升級了:例如用固態硬碟 (SSD) 取代機械硬碟、增加記憶體 (RAM),甚至更換處理器或整個系統。特別是固態硬碟,它能顯著提升系統效能,因為它能大幅縮短磁碟存取時間,從而使磁碟快取和虛擬記憶體運作得更加流暢。
總而言之,將良好的資料結構設計和記憶體存取模式與充分利用 CPU 快取相結合,並配合精心的 Windows 配置(更新、輕量級、無垃圾或不必要的進程、使用合適的電源計劃,並在必要時借助 ReadyBoost 等輔助工具或硬體改進),可以讓你從同一台機器中獲得更多,從而實現響應的應用程式和明顯的魔法系統,而奧本