1.前言
Cache在體系架構中占據半邊山,讀者又多為軟件從業者、學者,個人在碰到項目瓶頸時,研讀一些ARM手冊,以及業內技術論文,發現cache在架構中發揮著被軟件工程師低估的能力,本文從其設計角度和軟件角度闡述一二;
2.Cache的設計思考
Cache的基礎資料很多,多是圍繞如下展開說明:cache line,組/全相連,VIVT/VIPT/PIPT等概念,一般初學者閱讀后也會云里霧里,cache技術也很少被直接關注到;
所以在linux初級開發者接觸cache時,腦海里會不自覺的思考:硬件行為,都是被ICer設計好的;所以他們也并沒有深究cache的層次結構,也沒有繼續挖掘cache和驅動軟件的千絲萬縷的關系,腦海里想象的拓撲圖,大致是這樣:
認為cache的設計就是cpu和memory之間單一的存在,從而忽略了那些ICer對cache的研究和優化,直接影響就是軟件層面的優化,以及軟件層面的疑難bug;這也是初學者進階時的第一道阻礙;
那么在原廠工程師的腦海里,cache最基礎的樣子是這樣的:
它是現在處理器基本的形態,也是最簡單的形態,在ICer們的設計上,其內在協議直接影響著指令的流轉:load,store等;其內在存在的load buffer和store buffer影響著你的數據一致性,你的讀寫指令運行速度,數據的共享屬性等等,極其簡單的實例:
一個load執行,一個store執行,哪個快?顯然prefetch最快,再深一層次思考:如果工程中,在多cpu和多thread都有數據訪問需求,但是CPU和memory直接又有cache這一層大buffer,硬件和軟件都做了什么,能夠保證實時或訪存速度?
硬件上,制定cache的各種參數時,在保證滿足設計需求時,ICer們也會做這種動作:即對cache的benchmark;比如cache size和直接映射、組相連帶來的收益:
L2 cache的benchmark:
各種參數的測試結果呈現就是市面上大家可以查到的某種處理器L1 cache,L2 cache,L3 cache,以及system cache的大小,所以在大家認為很小size的cache,ICer以及架構師們,甚至是學者,都在為其能夠發揮出更佳性能,更低功耗的能力,夜以繼日的做研究,做實驗;
進一步思考:現在處理器設計越來越復雜,越來越強,比如NUMA,大小核等等,其呈現效果又如下簡單示例:
硬件層面帶來了考驗和升級,直接的影響給軟件層面也帶了考驗,比如:你的數據一致性問題,IP驅動設計等等,ARM的內存模型又是弱一致性的,那么你設計的驅動,可能被動存在著潛在bug,所以進一步帶來的是我們在工程問題上的思考。
1.Cache的工程思考
本人工作于ARM體系架構之上,所以日常在查閱arm官方公開的文檔時,知道的愈多,疑問也愈多,思考的也愈多,但是借助linux這個開源社區,眾多疑惑也慢慢得到解答,特此在工作之余將一小部分所得分享于大家,比如:cache的多個讀寫策略在影響著指令行為,直接導致數據的行為不一,如何在工程中認識它們?解決它們?
Cache的策略有如下:write-allocate,no write-allocate,read-allocate,read-through;
上述策略在驅動設計時,也是幾乎被忽略的存在,其發揮的作用就是data是否被緩存在cache中,還是 pass到內存中,若兩者皆存在,那么你的DMA在搬運數據前,有個動作就是sync,即刷新cache,保持數據在cache與內存中的一致性;
當然在內核驅動設計時,并不會指定使用哪個cache策略,因為kernel已經在某些接口中,潛在的做了相關操作,譬如大家用的ioremap_xxx這類接口就是和cache聯系緊密;
可以思考:如果我不需要使用ioremap_xxx這類接口,還需要關注什么cache策略嗎?
思考后的結果:dirty數據帶來的不同步就是你解決不了問題的噩夢;
Dirty數據怎么處理?借助linux的驅動設計,可以給各位呈現出如下一個接口:
POC(Pointof Coherency):全局緩存一致性,即系統中所有可以發起內存訪問的硬件單元的視角:CPU,DMA等;
所以雖然cache分為:L1 cache,L2 cache,L3cache,以及system cache,但是需要軟件設計者必須知道的是:你想干什么?是刷新部分master所感測到的數據,還是所有master都要關注到的數據變化,這就是cache帶來的可操作性;
即在不同cache層級的設計中,data的可觀測性是不一樣的,這也是為什么在我的腦海里,cache一直是多層級,多策略的,所以在驅動設計時,保證IP的視角看到的數據就是我設計的結果;
思考:如果只是CPU之間的data是可觀測的,有沒有什么指令作用域比POC更小的?
思考后的結果:POC視角太寬泛了,比POC作用域小的,即 POU:Pointof Unification;即處理器看到的視角,比如虛擬內存和物理內存映射的頁表數據:TLB,MMU;
進一步思考:POC和POU又太大了,有沒有只操作我dword數據的?
因為ARM的內存模型是弱一致性的,所以其在指令排序上有所行為,直接影響就是控制數據的亂序,內存屏障指令運勢而生:dmb,dsb,isb;(PS:宋寶華老師的分享文章有詳解);
該內存屏障指令宋老師有過介紹,不再贅述,需要關注的是:在使用上述指令時,也有作用域的區別;
Cache帶給處理器的是極致性能,帶給開發者是一個又一個的隱藏問題,所以剖析cache很有必要;
2.總結
本文因為篇幅問題,分享的是cache的冰山一角。cache又是體系架構中的一角,體系架構又是內核技術的一角,我又是眾多讀者的一角。
文獻參考:論文《WhatEvery Programmer Should Know About Memory》。
審核編輯 :李倩
-
ARM
+關注
關注
134文章
9143瀏覽量
368353 -
cpu
+關注
關注
68文章
10892瀏覽量
212477 -
Cache
+關注
關注
0文章
129瀏覽量
28375
原文標題:cache背后的軟思考
文章出處:【微信號:LinuxDev,微信公眾號:Linux閱碼場】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論