聽說你只知記憶體,而不知快取?CPU表示很傷心!

2022-09-18 11:15:22 字數 3604 閱讀 5774

一般我們的開發同學們都知道自己機器的cpu是幾核、記憶體是多大。但是對於cpu內部對程式效能影響較大的快取卻是一知半解。有些開發同學都是計算機的快取有l1、l2、l3,但是再詳細一點的問題,可能就很少有同學能答的完整了。如果下面這幾個問題你能脫口而出,請跳過本節。例如:

其實快取對計算機程式執行效能影響極大,但是他們在開發同學心目中的存在感卻不如記憶體高。要知道cpu快取以及快取演算法的設計是現代cpu設計的核心任務之一。飛哥覺得快取們一定感到很傷心。

其實在286之前的時代的cpu本是沒有快取的,因為當時的cpu和記憶體速度差異沒有現在這麼大,cpu直接訪問記憶體。但是到386時代,cpu和記憶體的速度不匹配了,第一次出現了快取。而且最早的快取並沒有放在cpu模組裡,而是放在主機板上的。再往後cpu越來越快,現在cpu的速度比記憶體要快百倍以上,所以就逐步演化出了l1、l2、l3**快取結構,而且都整合到的cpu晶元裡,以進一步提高訪問速度。

我們來看下現代intel的cpu架構的基本結構。

l1最接近於cpu,速度也最快,但是容量最小。一般現代cpu的l1會分成兩個,乙個用來cache data,乙個用來cache code,這是因為code和data的更新策略並不相同,而且因為cisc的變長指令,code cache要做特殊優化。 一般每個核都有自己獨立的data l1和code l1。

越往下,速度越慢,容量越大。l2一般也可以做到每個核乙個獨立的。但是l3一般就是整顆cpu共享的了。

uefiblog裡提供了乙個比較好的物理解剖圖,比較好地展示了出來:

上面介紹的只是籠統的概念。但是每個cpu的快取都是不一樣的,而且「紙上得來終覺淺」,我覺得我們還是有必要進行下一步的實機勘探工作。

linux的核心的開發者定義了一套框架模型來完成這一目的,它就是cpufreq系統。

cpufreq提供的sysfs介面,可以讓我們看到比/proc/cpuinfo更為詳細的cpu詳細資訊。

# cd /sys/devices/system/cpu/;ll

drwxr-xr-x 7 root root 0 apr 15 15:29 cpu0

drwxr-xr-x 7 root root 0 apr 15 15:29 cpu1

......

# cat cpu0/cache/index0/level  

1 # cat cpu0/cache/index0/size

32k

# cat cpu0/cache/index0/type

data

# cat cpu0/cache/index0/shared_cpu_list

0,12

# cat cpu0/cache/index1/level

1# cat cpu0/cache/index1/size

32k

# cat cpu0/cache/index1/type

instruction

# cat cpu0/cache/index1/shared_cpu_list

0,12

從上面的level介面可以看出index0和index1都是一級快取,只不過乙個是data資料快取,乙個是instruction也就是**快取。

等等,上面提到的是每個core是獨立的l1快取,為什麼shared_cpu_list顯示有共享?對了我們這裡看到的cpu0並不是物理core,而是邏輯核,都是超執行緒技術虛擬出來的。 實際上cpu0和cpu12是屬於乙個物理core,所以每個data l1和instruction是這兩個邏輯核共享的。

我的這台電腦裡,總共是有12個data l1,12個instrunction l1,大小都是32k。

# cat cpu0/cache/index2/size  

256k

# cat cpu0/cache/index2/type

unified

# cat cpu0/cache/index2/shared_cpu_list

0,12

二級快取要比一級快取大不少,有256k,但是不分data和instruction。另外l2和l1一樣,也是總共有12個,每兩個邏輯核共享乙個l2。

# cat cpu0/cache/index3/size  

12288k

# cat cpu0/cache/index3/type

unified

# cat cpu0/cache/index3/shared_cpu_list

0-5,12-17

#cat cpu6/cache/index3/shared_cpu_list

6-11,18-23

l3達到了12m,你去買cpu的時候商品裡能看到的快取屬性一般告訴你的就是這個l3屬性。因為l3要比l2和l1看起來要大的多,能激發你購買的慾望。但實際上我的這台電腦裡l3只有兩個,每個cpu各乙個,不像是l2、l1有很多。第0-5,12-17號邏輯核共享乙個l3,因為它們是在乙個物理cpu上。6-11,18-23共享另乙個。

另外,linux上還有個dmidecode命令,也能檢視到一些關於cpu快取的資訊,感興趣的小夥伴們可以試試

# dmidecode -t cache
可能有的同學會問了,我用的作業系統是windows啊,怎麼看?開啟cmd命令列,輸入以下命令試試吧,飛哥在windows上知道的就這麼多了,感興趣的話你自己google上搜搜吧。

# wmic cpu get l2cachesize,l3cachesize
cache line:我們前面只介紹了各個級別的快取,但是這裡面有個很重要的概念就是cache line,就是本級快取向下一層取資料時的基本單位。可以通過如下方式檢視:

# cd /sys/devices/system/cpu/;ll

# cat cpu0/cache/index0/coherency_line_size

64# cat cpu0/cache/index1/coherency_line_size

64# cat cpu0/cache/index2/coherency_line_size

64# cat cpu0/cache/index3/coherency_line_size

64

可以看到l1、l2、l3的cache line大小都是64位元組(注意是位元組)。就是說每次cpu從記憶體獲取資料的時候,都是以該單位來進行的,哪怕你只取乙個bit,cpu也是給你取乙個cache line然後放到各級快取裡存起來。請大家牢牢記住這個概念,以後的文章中我們會用到。

開發內功修煉之cpu篇**:

建議你使用LocalDateTime而不是Date

但是這三步不是原子操作 多執行緒併發如何保證執行緒安全 避免執行緒之間共享乙個 dateformat物件,每個執行緒使用時都建立一次 dateformat物件 建立和銷毀物件的開銷大 對使用format和parse方法的地方進行加鎖 執行緒阻塞性能差 使用threadlocal保證每個執行緒最多隻建...

sync不生效 vue vue 聽說你很會傳值?

大小 vue 專案都離不開元件通訊,在這裡總結一下vue元件通訊方式並列出,都是簡單的例子.適合像我這樣的小白。如有錯誤,歡迎指正。son.vue copyexport default mounted copyson.vue copyexport default copy控制台列印 我是子元件的值 ...

不,你孩子患上的是弱視而不是近視

對不起,你的孩子是弱視.最近希小瑪在醫院聽到這樣一段對話 醫生,我家孩子眼睛到底是怎麼了?為什麼戴上眼鏡也看不清楚,是配鏡的度數不夠嗎?不,你孩子患上的是弱視而不是近視.家長一臉茫然的看著醫生,問 弱視是什麼?當家長們將注意力放在如何預防孩子患上近視的時候,殊不知弱視也有可能悄悄盯上孩子了!弱視弱視...