syslog 向内存中缓存_漫谈缓存(Cache)、大规模芯片系统的存储层次结构优化以及开源仿真工具ZSim...
這次的話題將從緩存開始,以一種易于理解的方式向大家呈現緩存的基本概念,然后拓展至大規模芯片系統的非均一訪問延時的緩存訪問問題,最后簡要介紹一種緩存仿真工具——ZSim。
緩存的概念
處理器和內存之間存在巨大的速度差距。
處理器可以稱得上是整個計算系統中最勤勞的成員:它的終生目標就是每個周期不停地取指令、解決依賴、計算、存取數據。然而,當處理器伸手向內存索取數據時,內存卻需要讓它等待上百個周期。巧婦難為無米之炊,在等待內存返回數據之前,處理器只能干等著,或者嘗試完成其他的計算(亂序執行處理器)。
毫無疑問的是,如果每次處理器訪問內存均需等待上百個周期,那這處理器的最終表現也好不到哪去了。為了“喂飽”處理器的數據需求,架構師們向處理器中添加了緩存結構。
緩存(Cache)是利用處理器訪問內存的局部性而設計的硬件結構,緩存的基石是概率,緩存比內存小得多,多采用SRAM。一般地,處理器訪問地址會有以下規律:時間局部性,即訪問了該地址之后,還有較大可能會訪問該地址;空間局部性,即訪問了該地址之后,還有較大可能會訪問相鄰地址。緩存的終極目標是盡可能把處理器將要訪問的所有內存地址上的數據都準備好:一旦處理器需要這些數據,緩存可以在幾個周期內就將數據雙手奉上,也就是緩存命中。如果處理器需要的數據不在緩存中,就會發生緩存缺失。
用一個形象的比喻:小明想在家里看書。當他想閱讀某系列的某一本書時,需要從一千米遠的圖書館找到該書,然后拿著書回到家并開始閱讀。于是每次他都要去圖書館拿書,閱讀后返回圖書館,將書放回,還要加上二千米的路程。如此操作實再太過麻煩,以至于小明終于想到了一個辦法:每次取書都抱著整個系列的書回家,把多余的書放在自己的書柜上,拿起一本并開始閱讀。假設圖書館沒有借書限制。
在這個比喻中,小明好比處理器,小明的書柜充當著緩存的角色,而圖書館就算內存了。書柜中放著整個系列的書,是因為小明在讀完當前這一本后,還有很大的可能讀系列中其余幾本(空間局部性);小明讀完當前這一本后,還有很大的可能還要再回顧這一本書(時間局部性)。而一旦小明能夠在自己的書柜上拿到接下來要讀的書,就無需再到圖書館去取(緩存命中),節省了時間;而小明讀完了整個系列的書,想要讀其他系列的書,就無法從書柜上獲得(緩存缺失),于是還要前往圖書館。
回到緩存本身。緩存中保存的數據實際是所有內存數據的一個子集。這個子集的厲害之處在于經常能覆蓋處理器所需要訪問的地址。為了使這個子集能夠生效,緩存還需要做到以下幾點:
對以上第三點作一個說明。還是小明,如果他想閱讀的書的系列或者種類發生了變化,就還是必須去圖書館取書,而不是從書架上找。
正如從書柜上取書很快一樣,緩存的快速正是因為緩存比內存小得多,譯碼電路簡單;此外,緩存所采用的SRAM本身的速度也遠遠快于內存常使用的DRAM。如果小明的書柜與圖書館一樣大,那找本書估計也會相當費時。但是緩存的小容量同樣也容易導致緩存缺失。增大緩存會增加緩存命中延時,但有助于減少緩存缺失,因而形成了一個折中問題:要保證命中延時不太大的同時,緩存缺失的頻率也可以接受。該折中問題常常受處理器周期長度的影響。
有一天,小明覺得自己的書柜太小,以至于他還是要經常跑圖書館。聰明的小明在自家的倉庫里又放了一個大書柜。當小明無法在自己的書柜上找到想要的書時,他會去倉庫的書柜中尋找。如此,小明去圖書館的次數更少了。
這就形成兩級緩存:小明的書柜是一級緩存,而倉庫里的大書柜是二級緩存。一般地,從最靠近處理器流水線的緩存開始,每一級的緩存都依次增大,命中延時也相應增加。在當前緩存中發生了緩存缺失的地址,有可能在下一級緩存發生緩存命中,就能避免造訪內存。
對于大規模芯片系統,緩存結構需要解決什么問題?
在大規模芯片系統(核心數量巨大)的情況下,為了提高緩存的利用率,通常多個核心會共享最外層緩存。核心的增多,使得共享的緩存不斷增大,以至于該級緩存命中延時太高、功耗明顯增加,使得該級緩存失去了意義。
以上所述的情況,緩存均為一整塊,而訪問緩存中的某個數據,發生緩存命中時均造成固定的延時。因此這種鐵板一塊的緩存也被稱為均一訪問延時(Uniform Cache Access, UCA)的緩存。
為了降低這個臃腫的最外層共享緩存的命中延時,架構師們將它掰成多塊,每個處理器核心附近都放一塊。處理器核心和它的私有緩存和一部分的共享緩存形成了一個可以重復的單元,就好像整齊平鋪的瓦片(Tile)一樣。一個片上網絡連接這些不同的瓦片,實現消息互通。因為片上網絡帶來的不確定延時,緩存的這種組織方式稱為非均一訪問延時(Non-Uniform Cache Access,NUCA)。具體表現在:在發生緩存命中時,某核心訪問它本地的這部分共享緩存,與訪問其它核心擁有的共享緩存的延時不同;某核心訪問與它較接近的共享緩存,與訪問與它較遠的共享緩存的延時不同。
既然NUCA擁有一個分布式的最外側緩存,如何將地址映射到這些可重復的單元(Tile)上,是一個問題。經典的做法是將數據以地址交錯(Address-Interleaved)的形式,依次落到不同核心所在的Tile。
此例中,對于特定的地址,NUCA只會將其映射到一個邏輯上確定的Tile上,因而稱為靜態(Static)NUCA。既然有靜態NUCA那就必然有動態(Dynamic)NUCA——基本思路是打破地址與Tile的確定關系,“動態”體現在要依靠程序運行期間被緩存收集的信息來完成地址到Tile的映射。動態NUCA,以引入一層額外邏輯的代價,以優化地址映射的形式,達到減少NUCA訪問延時的目的。動態NUCA的具體實現方式千差萬別,有興趣的小伙伴可以尋找一些相關文獻深入研究。緩存一致性(Cache Coherency)在多/眾核的情形下,也是一個需要額外注意的問題,但此處篇幅所限,暫且留作日后討論。
緩存仿真工具——ZSim
大規模芯片系統的開發周期很長,我們不能等到整個系統的電路都確定之后,再回過頭去修改并優化緩存的層次。也就是說,我們需要一個方法能夠快速得到某個多/眾核系統的大致性能表現。在這種需求的推動下,Daniel Sanchez在斯坦福大學開發了ZSim,用于快速實現大型異構芯片的架構探索和設計[1]。之后,ZSim又陸續經過幾次功能增強。ZSim以一種垂直的方式對多級緩存構成的存儲器層次結構建模,每級緩存之間均以父子關系相互指向,因而能用于多核甚至眾核情形下的仿真。
現在,ZSim是一個開源的,基于Pin的x86緩存仿真工具,它的優勢有:
筆者從ZSim提供的Vagrant file中總結了搭建方法:
系統要求:Ubuntu 12(理論上其他Ubuntu系統也可,但Ubuntu12搭建不容易出錯)
export DEBIAN_FRONTEND=noninteractive apt-get -y update apt-get -y dist-upgrade安裝依賴
apt-get -y install build-essential g++ git scons apt-get -y install libelfg0-dev libhdf5-serial-dev libconfig++-dev apt-get -y install gfortran openjdk-7-jdk安裝vim
apt-get -y install vim安裝pin
sudo wget http://software.intel.com/sites/landingpage/pintool/downloads/pin-2.14-71313-gcc.4.4.7-linux.tar.gz sudo tar xzf pin-2.14-71313-gcc.4.4.7-linux.tar.gz echo "export PINPATH=~/pin-2.14-71313-gcc.4.4.7-linux" >> ~YOUR_USERNAME/.bashrc注意pin的版本,以及設置環境變量時你的用戶名
設置Linux內存參數,以及進程監視權限
sysctl -w kernel.shmmax=1073741824 sysctl -w kernel.yama.ptrace_scope=0安裝ZSim
git clone https://github.com/s5z/zsim.git cd zsim scons -jN運行例程
./build/opt/zsim tests/simple.cfgZSim將打印出一個out.cfg文件,其中記載了仿真的系統的詳細配置情況。同時ZSim也提供HDF5格式的輸出,供數據處理之用。
注意安裝ZSim時要保證gcc版本至少為4.6。篇幅所限,更詳細的配置和運行指導請參閱ZSim目錄的md文件。此外,要設計額外的緩存模型需要先閱讀源碼。幾句話送給準備閱讀ZSim源碼(C++)的小伙伴們:
本篇小結
緩存的設計,與內存、地址翻譯等問題交雜在一起,形成體系結構中一塊很大的領域——存儲器層次結構。通過閱讀本篇文章,小伙伴們應該對緩存的存在意義和基本工作原理有了一定的認識。然而,正如某位大牛說的,"The devil is in the details.",緩存的狀態更新并不是原子的,因而需要面臨過渡態和冒險等等實際問題。所以還是那句話:千里之行,始于足下。
參考
總結
以上是生活随笔為你收集整理的syslog 向内存中缓存_漫谈缓存(Cache)、大规模芯片系统的存储层次结构优化以及开源仿真工具ZSim...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 心电图前波过多_心电图写着:T波倒置,就
- 下一篇: 拖尾因子大怎么调整_乳房松弛下垂怎么改善