1. cpu中的cache結構及cache一致性算法
一. 引子瀏覽器
在多線程環境中,常常會有一些計數操做,用來統計線上服務的一些qps、平均延時、error等。爲了完成這些統計,能夠實現一個多線程環境下的計數器類庫,方便記錄和查看用戶程序中的各種數值。在實現這個計數器類庫時,能夠利用thread local存儲來避免cache bouncing,從而提升效率。注意,這種實現方式的本質是把寫時的競爭轉移到了讀:讀得合併全部寫過的線程中的數據,而不可避免地變慢了。當你讀寫都很頻繁並得基於數值作一些邏輯判斷時,你不該該用前述的實現方式。那麼,cache bouncing是什麼?下面詳細說明一下。緩存
二. 什麼是cache bouncing?安全
爲了以較低的成本大幅提升性能,現代CPU都有cache。cpu cache已經發展到了三級緩存結構,基本上如今買的我的電腦都是L3結構。其中L1和L2cache爲每一個核獨有,L3則全部核共享。爲了保證全部的核看到正確的內存數據,一個核在寫入本身的L1 cache後,CPU會執行Cache一致性算法把對應的cacheline(通常是64字節)同步到其餘核。這個過程並不很快,是微秒級的,相比之下寫入L1 cache只須要若干納秒。當不少線程在頻繁修改某個字段時,這個字段所在的cacheline被不停地同步到不一樣的核上,就像在覈間彈來彈去,這個現象就叫作cache bouncing。因爲實現cache一致性每每有硬件鎖,cache bouncing是一種隱式的的全局競爭。
服務器
cache bouncing使訪問頻繁修改的變量的開銷陡增,甚至還會使訪問同一個cacheline中不常修改的變量也變慢,這個現象是false sharing。按cacheline對齊能避免false sharing,但在某些狀況下,咱們甚至還能避免修改「必須」修改的變量。當不少線程都在累加一個計數器時,咱們讓每一個線程累加私有的變量而不參與全局競爭,在讀取時咱們累加全部線程的私有變量。雖然讀比以前慢多了,但因爲這類計數器的讀多爲低頻展示,慢點無所謂。而寫就快多了,從微秒到納秒,幾百倍的差距。網絡
三. cachesession
1. cache的意義多線程
爲何須要CPU cache?由於CPU的頻率太快了,快到主存跟不上,這樣在處理器時鐘週期內,CPU經常須要等待主存,浪費資源。因此cache的出現,是爲了緩解CPU和內存之間速度的不匹配問題(結構:cpu -> cache -> memory)。架構
CPU cache有什麼意義?cache的容量遠遠小於主存,所以出現cache miss在所不免,既然cache不能包含CPU所須要的全部數據,那麼cache的存在真的有意義嗎?固然是有意義的——局部性原理。工具
A. 時間局部性:若是某個數據被訪問,那麼在不久的未來它極可能被再次訪問;
B. 空間局部性:若是某個數據被訪問,那麼與它相鄰的數據很快也可能被訪問;
2. cache和寄存器
存儲器的三個性能指標——速度、容量和每位價格——致使了計算機組成中存儲器的多級層次結構,其中主要是緩存和主存、主存和磁盤的結構。那麼在主存之上,cache和寄存器之間的關係是?
舉個例子,當你在思考一個問題的時候,寄存器存放的是你當前正在思考的內容,cache存放的是與該問題相關的記憶,主存則存放不管與該問題是否有關的全部記憶,因此,寄存器存放的是當前CPU執行的數據,而cache則緩存與該數據相關的部分數據,所以只要保證了cache的一致性,那麼寄存器拿到的數據也必然具有一致性。
四. CPU cache結構
1. 單核CPU cache結構
在單核CPU結構中,爲了緩解CPU指令流水中cycle衝突,L1分紅了指令(L1P)和數據(L1D)兩部分,而L2則是指令和數據共存。
2. 多核CPU cache結構
多核CPU的結構與單核類似,可是多了全部CPU共享的L3三級緩存。在多核CPU的結構中,L1和L2是CPU私有的,L3則是全部CPU核心共享的。
五. MESI(緩存一致性)
cache的寫操做方式能夠追溯到大學教程《計算機組成原理》一書。
A. write through(寫通):每次CPU修改了cache中的內容,當即更新到內存,也就意味着每次CPU寫共享數據,都會致使總線事務,所以這種方式經常會引發總線事務的競爭,高一致性,可是效率很是低;
B. write back(寫回):每次CPU修改了cache中的數據,不會當即更新到內存,而是等到cache line在某一個必須或合適的時機纔會更新到內存中;
不管是寫通仍是寫回,在多線程環境下都須要處理緩存cache一致性問題。爲了保證緩存一致性,處理器又提供了寫失效(write invalidate)和寫更新(write update)兩個操做來保證cache一致性。
寫失效:當一個CPU修改了數據,若是其餘CPU有該數據,則通知其爲無效;
寫更新:當一個CPU修改了數據,若是其餘CPU有該數據,則通知其跟新數據;
寫更新會致使大量的更新操做,所以在MESI協議中,採起的是寫失效(即MESI中的I:ivalid,若是採用的是寫更新,那麼就不是MESI協議了,而是MESU協議)。
2. cache line
cache line是cache與內存數據交換的最小單位,根據操做系統通常是32byte或64byte。在MESI協議中,狀態能夠是M、E、S、I,地址則是cache line中映射的內存地址,數據則是從內存中讀取的數據。
工做方式:當CPU從cache中讀取數據的時候,會比較地址是否相同,若是相同則檢查cache line的狀態,再決定該數據是否有效,無效則從主存中獲取數據,發起一次RR(remote read);
工做效率:當CPU可以從cache中拿到有效數據的時候,消耗幾個CPU cycle,若是發生cache miss,則會消耗幾十上百個CPU cycle;
cache的工做原理以及在主板上的結構以下兩圖所示:
3. 狀態介紹
MESI協議將cache line的狀態分紅modify、exclusive、shared、invalid,分別是修改、獨佔、共享和失效。
modify:當前CPU cache擁有最新數據(最新的cache line),其餘CPU擁有失效數據(cache line的狀態是invalid),雖然當前CPU中的數據和主存是不一致的,可是以當前CPU的數據爲準;
exclusive:只有當前CPU中有數據,其餘CPU中沒有改數據,當前CPU的數據和主存中的數據是一致的;
shared:當前CPU和其餘CPU中都有共同數據,而且和主存中的數據一致;
invalid:當前CPU中的數據失效,數據應該從主存中獲取,其餘CPU中可能有數據也可能無數據,當前CPU中的數據和主存被認爲是不一致的;
對於invalid而言,在MESI協議中採起的是寫失效(write invalidate)。
4. cache操做
MESI協議中,每一個cache的控制器不只知道本身的操做(local read和local write),經過監聽也知道其餘CPU中cache的操做(remote read和remote write)。對於本身本地緩存有的數據,CPU僅須要發起local操做,不然發起remote操做,從主存中讀取數據,cache控制器經過總線監聽,僅可以知道其餘CPU發起的remote操做,可是若是local操做會致使數據不一致性,cache控制器會通知其餘CPU的cache控制器修改狀態。
local read(LR):讀本地cache中的數據;
local write(LW):將數據寫到本地cache;
remote read(RR):讀取內存中的數據;
remote write(RW):將數據寫通到主存;
5. 狀態轉換和cache操做
如上文內容所述,MESI協議中cache line數據狀態有4種,引發數據狀態轉換的CPU cache操做也有4種,所以要理解MESI協議,就要將這16種狀態轉換的狀況討論清楚。
MESI協議爲了保證多個CPU cache中共享數據的一致性,定義了cache line的四種狀態,而CPU對cache的4種操做可能會產生不一致狀態,所以cache控制器監聽到本地操做和遠程操做的時候,須要對地址一致的cache line狀態作出必定的修改,從而保證數據在多個cache之間流轉的一致性。
2. 客戶端-服務器模式架構
客戶端-服務器模式
定義:客戶端-服務器模式(Client–server model)簡稱C/S結構,是一種網絡架構,它把客戶端 (Client) 與服務器 (Server) 區分開來。每個客戶端軟件的實例均可以向一個服務器或應用程序服務器發出請求。
C/S結構:Client/Server結構(C/S結構)是你們熟知的客戶機和服務器結構。它是軟件系統體系結構,經過它能夠充分利用兩端硬件環境的優點,將任務合理分配到Client端和Server端來實現,下降了系統的通信開銷。
這是一個過程,這一般使得信息請求。獲得迴應後,這一過程可能會終止或可能會作一些其餘的處理。
例如: 互聯網瀏覽器做爲一個客戶端應用程序,Web服務器發送一個請求到獲得一個HTML網頁。
它接受一個來自客戶端的請求的過程。得到來自客戶端的請求後會處理所需的收集所需的信息,將其發送到請求客戶端。一旦這樣作完成後,就又變成準備爲另外一個客戶端。服務器進程始終等待準備用於處理傳入請求。
實例: Web服務器一直等待來自互聯網瀏覽器的請求,並儘快獲得任何請求從瀏覽器,它拿起一個請求的HTML頁面,並把它發送回該瀏覽器。
注意,客戶端須要知道的存在服務器的地址,可是服務器並不須要在創建的鏈接以前知道客戶端的地址。一旦創建鏈接後,雙方均可以發送和接收信息。
有兩種類型的客戶端服務器架構:
兩層構架: 在這種架構中,客戶端直接與服務器進行交互。這種類型的架構可能有一些安全漏洞和性能問題。 IE瀏覽器和Web服務器的兩層架構。這裏的安全問題都解決了使用安全套接字層(SSL)。
三層架構:在這個架構中,多了一個軟件位於客戶端和服務器之間。這中間的軟件被稱爲中間件。中間件被用來執行全部的安全檢查和重負載狀況下的負載平衡。中間件須要從客戶端的全部請求,並作必要的驗證後,經過向服務器發出請求。而後,服務器沒有所需的處理和發送響應回中間件,中間件終於經過這個響應返回給客戶端。若是想實現一個3層架構,那麼可使用如Web Logic或WebSphere軟件在Web服務器和Web瀏覽器之間的任何中間件。
優勢:
(1)可實現資源共享。C/L結構中的資源是分佈的,客戶機與服務器具備一對多的關係和運行環境。用戶不只可存取在服務器和本地工做站上的資源,還能夠享用其餘工做站上的資源,實現了資源共享。
(2)可實現管理科學化和專業化。系統中的資源分佈在各服務器和工做站上,能夠採用分層管理和專業化管理相結合的方式,用戶有權去充分利用本部門、本領域的專業知識來參與管理,使得各級管理更加科學化和專業化。
(3)可快速進行信息處理。因爲在 C/S 結構中是一種基於點對點的運行環境,當一項任務提出請求處理時,能夠在全部可能的服務器間均衡地分佈該項任務的負載。這樣,在客戶端發出的請求可由多個服務器來並行進行處理,爲每一項請求提供了極快的響應速度和較高的事務吞吐量。
(4)能更好地保護原有的資源。因爲C/S是一種開放式的結構,可有效地保護原有的軟、硬件資源。之前,在其餘環境下積累的的數據和軟件都可在C/S中經過集成而保留使用,而且能夠透明地訪問多個異構的數據源和自由地選用不一樣廠家的數據應用開發工具,具備高度的靈活性;而之前的硬件亦可徹底繼續使用,當在系統中增長硬件資源時,不會減弱系統的能力,同時客戶機和服務器都可單獨地升級,故具備極好的可擴充性。
3. 局域網通訊原理
上圖中連線應該是雙向箭頭,這裏就不在進行修改了
局域網中A和B進行通訊,能夠直接鏈接網線。但當局域網中計算機比較多的時候呢?都鏈接網線嗎?顯然這種作法不太行。由此交換機就應運而生。
局域網間多個計算機進行相互通訊,依靠的就是交換機。下面說一下計算機之間進行通信的詳細流程。在這以前先了解一下網絡的層次。這裏以五層爲例;
================================
應用層
傳輸層(端口號 TCP.UDP等協議)
網絡層
數據鏈路層(ARP地址解析協議)
物理層 (網線等)
================================
好比A、C間進行通訊:
A第一次找C時,會經過廣播的形式來通知局域網內的其餘計算機(這裏爲B,C)。C則會經過地址解析協議(ARP)將本身的IP與MAC進行綁定,而後發送給A。A中此時有C的
IP-MAC,下次A會將MAC地址發送給交換機,從而查找C,進而找到C中對應的進程端口號(計算機之間的交互,其實就是各個進程之間的交互)。