色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

CPU緩存那些事兒

dyquk4xk2p3d ? 來源:CSDN ? 2023-09-10 10:57 ? 次閱讀

	

	

	

CPU高速緩存集成于CPU的內部,其是CPU可以高效運行的成分之一,本文圍繞下面三個話題來講解CPU緩存的作用:

  • 為什么需要高速緩存?

  • 高速緩存的內部結構是怎樣的?

  • 如何利用好cache,優化代碼執行效率?

為什么需要高速緩存?

在現代計算機的體系架構中,為了存儲數據,引入了下面一些元件

  • 1.CPU寄存器

  • 2.CPU高速緩存

  • 3.內存

  • 4.硬盤

從1->4,速度越來越慢,價格越來越低,容量越來越大。這樣的設計使得一臺計算機的價格會處于一個合理的區間,使得計算機可以走進千家萬戶。

由于硬盤的速度比內存訪問慢,因此我們在開發應用軟件時,經常會使用redis/memcached這樣的組件來加快速度。

而由于CPU和內存速度的不同,于是產生了CPU高速緩存。

下面這張表反應了CPU高速緩存和內存的速度差距。

存儲器類型

時鐘周期

L1 cache

4

L2 cache

11

L3 cache

24

內存

167

通常cpu內有3級緩存,即L1、L2、L3緩存。其中L1緩存分為數據緩存指令緩存,cpu先從L1緩存中獲取指令和數據,如果L1緩存中不存在,那就從L2緩存中獲取。每個cpu核心都擁有屬于自己的L1緩存和L2緩存。如果數據不在L2緩存中,那就從L3緩存中獲取。而L3緩存就是所有cpu核心共用的。如果數據也不在L3緩存中,那就從內存中獲取了。當然,如果內存中也沒有那就只能從硬盤中獲取了。

683ef7ee-4f7e-11ee-a25d-92fbcf53809c.png

對這樣的分層概念有了了解之后,就可以進一步的了解高速緩存的內部細節。

高速緩存的內部結構

CPU Cache 在讀取內存數據時,每次不會只讀一個字或一個字節,而是一塊塊地讀取,這每一小塊數據也叫CPU 緩存行(CPU Cache Line)。這也是對局部性原理的運用,當一個指令或數據被拜訪過之后,與它相鄰地址的數據有很大概率也會被拜訪,將更多或許被拜訪的數據存入緩存,可以進步緩存命中率。

cache line 又分為多種類型,分別為直接映射緩存多路組相連緩存全相連緩存

下面依次介紹。

直接映射緩存

直接映射緩存會將一個內存地址固定映射到某一行的cache line。

其思想是將一個內存地址劃分為三塊,分別是Tag, Index,Offset(這里的內存地址指的是虛擬內存)。將cacheline理解為一個數組,那么通過Index則是數組的下標,通過Index就可以獲取對應的cache-line。再獲取cache-line的數據后,獲取其中的Tag值,將其與地址中的Tag值進行對比,如果相同,則代表該內存地址位于該cache line中,即cache命中了。最后根據Offset的值去data數組中獲取對應的數據。整個流程大概如下圖所示:

685a8a40-4f7e-11ee-a25d-92fbcf53809c.png

下面是一個例子,假設cache中有8個cache line,

686da8a0-4f7e-11ee-a25d-92fbcf53809c.png

對于直接映射緩存而言,其內存和緩存的映射關系如下所示:

688dff88-4f7e-11ee-a25d-92fbcf53809c.jpg

從圖中我們可以看出,0x00,0x40,0x80這三個地址,其地址中的index成分的值是相同的,因此將會被加載進同一個cache line。

試想一下如果我們依次訪問了0x00,0x40,0x00會發生什么?

當我們訪問0x00時,cache miss,于是從內存中加載到第0行cache line中。當訪問0x40時,第0行cache line中的tag與地址中的tag成分不一致,因此又需要再次從內存中加載數據到第0行cache line中。最后再次訪問0x00時,由于cache line中存放的是0x40地址的數據,因此cache再次miss。可以看出在這個過程中,cache并沒有起什么作用,訪問了相同的內存地址時,cache line并沒有對應的內容,而都是從內存中進行加載。

這種現象叫做cache顛簸(cache thrashing)。針對這個問題,引入多路組相連緩存。下面一節將講解多路組相連緩存的工作原理

多路組相連緩存

多路組相連緩存的原理相比于直接映射緩存復雜一些,這里將以兩路組相連這種場景來進行講解。

所謂多路就是指原來根據虛擬的地址中的index可以唯一確定一個cache line,而現在根據index可以找到多行cache line。而兩路的意思就是指通過index可以找到2個cache line。在找到這個兩個cache line后,遍歷這兩個cache line,比較其中的tag值,如果相等則代表命中了。

68bf3fda-4f7e-11ee-a25d-92fbcf53809c.png

下面還是以8個cache line的兩路緩存為例,假設現在有一個虛擬地址是0000001100101100,其tag值為0x19,其index為1,offset為4。那么根據index為1可以找到兩個cache line,由于第一個cache line的tag為0x10,因此沒有命中,而第二個cache line的tag為0x19,值相等,于是cache命中。

68d78572-4f7e-11ee-a25d-92fbcf53809c.png

對于多路組相連緩存而言,其內存和緩存的映射關系如下所示:

68f6d6d4-4f7e-11ee-a25d-92fbcf53809c.jpg

由于多路組相連的緩存需要進行多次tag的比較,對于比直接映射緩存,其硬件成本更高,因為為了提高效率,可能會需要進行并行比較,這就需要更復雜的硬件設計。

另外,如何cache沒有命中,那么該如何處理呢?

以兩路為例,通過index可以找到兩個cache line,如果此時這兩個cache line都是處于空閑狀態,那么cache miss時可以選擇其中一個cache line加載數據。如果兩個cache line有一個處于空閑狀態,可以選擇空閑狀態的cache line 加載數據。如果兩個cache line都是有效的,那么則需要一定的淘汰算法,例如PLRU/NRU/fifo/round-robin等等。

這個時候如果我們依次訪問了0x00,0x40,0x00會發生什么?

當我們訪問0x00時,cache miss,于是從內存中加載到第0路的第0行cache line中。當訪問0x40時,第0路第0行cache line中的tag與地址中的tag成分不一致,于是從內存中加載數據到第1路第0行cache line中。最后再次訪問0x00時,此時會訪問到第0路第0行的cache line中,因此cache就生效了。由此可以看出,由于多路組相連的緩存可以改善cache顛簸的問題。

全相連緩存

從多路組相連,我們了解到其可以降低cache顛簸的問題,并且路數量越多,降低cache顛簸的效果就越好。那么是不是可以這樣設想,如果路數無限大,大到所有的cache line都在一個組內,是不是效果就最好?基于這樣的思想,全相連緩存相應而生。

6925f4fa-4f7e-11ee-a25d-92fbcf53809c.png

下面還是以8個cache line的全相連緩存為例,假設現在有一個虛擬地址是0000001100101100,其tag值為0x19,offset為4。依次遍歷,直到遍歷到第4行cache line時,tag匹配上。

693e543c-4f7e-11ee-a25d-92fbcf53809c.jpg

全連接緩存中所有的cache line都位于一個組(set)內,因此地址中將不會劃出一部分作為index。在判斷cache line是否命中時,需要遍歷所有的cache line,將其與虛擬地址中的tag成分進行對比,如果相等,則意味著匹配上了。因此對于全連接緩存而言,任意地址的數據可以緩存在任意的cache line中,這可以避免緩存的顛簸,但是與此同時,硬件上的成本也是最高。

如何利用緩存寫出高效率的代碼?

看下面這個例子,對一個二維數組求和時,可以進行按行遍歷和按列遍歷,那么哪一種速度會比較快呢?

const int row = 1024;
const int col = 1024;
int matrix[row][col];

//按行遍歷
int sum_row = 0;
for (int r = 0; r < row; r++) {
    for (int c = 0; c < col; c++) {
        sum_row += matrix[r][c];
    }
}

//按列遍歷
int sum_col = 0;
for (int c = 0; c < col; c++) {
    for (int r = 0; r < row; r++) {
        sum_col += matrix[r][c];
    }
}

我們分別編寫下面的測試代碼,首先是按行遍歷的時間:

#include 
#include 
const int row = 1024;
const int col = 1024;
int matrix[row][col];

//按行遍歷
int main(){
    for (int r = 0; r < row; r++) {
        for (int c = 0; c < col; c++) {
            matrix[r][c] = r+c;
        }
    }
    auto start = std::now();
    
    //按行遍歷
    int sum_row = 0;
    for (int r = 0; r < row; r++) {
        for (int c = 0; c < col; c++) {
            sum_row += matrix[r][c];
        }
    }

    auto finish = std::now();
    auto duration = std::duration_cast<std::milliseconds>(finish - start);
    std::cout << duration.count() << "ms" << std::endl;
}

標準輸出打印了:2ms

接著是按列遍歷的測試代碼:

#include 
#include 
const int row = 1024;
const int col = 1024;
int matrix[row][col];

//按行遍歷
int main(){
    for (int r = 0; r < row; r++) {
        for (int c = 0; c < col; c++) {
            matrix[r][c] = r+c;
        }
    }
    auto start = std::now();
    
    //按列遍歷
    int sum_col = 0;
    for (int c = 0; c < col; c++) {
        for (int r = 0; r < row; r++) {
            sum_col += matrix[r][c];
        }
    }

    auto finish = std::now();
    auto duration = std::duration_cast<std::milliseconds>(finish - start);
    std::cout << duration.count() << "ms" << std::endl;
}

標準輸出打印了:8ms

答案很明顯了,按行遍歷速度比按列遍歷快很多。

原因就是按行遍歷時, 在訪問matrix[r][c]時,會將后面的一些元素一并加載到cache line中,那么后面訪問matrix[r][c+1]和matrix[r][c+2]時就可以命中緩存,這樣就可以極大的提高緩存訪問的速度。

如下圖所示,在訪問matrix[0][0]時,matrix[0][1],matrix[0][2],matrix[0][2]也被加載進了高速緩存中,因此隨后遍歷時就可以用到緩存。

694f9e2c-4f7e-11ee-a25d-92fbcf53809c.jpg

而按列遍歷時,訪問完matrix[0][0]之后,下一個要訪問的數據是matrix[1][0],不在高速緩存中,于是需要再次訪問內存,這就使得程序的訪問速度相較于按行緩存會慢很多。


聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • cpu
    cpu
    +關注

    關注

    68

    文章

    10870

    瀏覽量

    211880
  • 內存
    +關注

    關注

    8

    文章

    3028

    瀏覽量

    74077
  • 數組
    +關注

    關注

    1

    文章

    417

    瀏覽量

    25957

原文標題:CPU緩存那些事兒

文章出處:【微信號:良許Linux,微信公眾號:良許Linux】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    Linux內存的那些事兒

    CPU、IO、磁盤、內存,可以說是影響計算機性能的幾大關鍵因素。今天,我們就來探究一下內存的那些事兒
    發表于 09-08 14:16 ?766次閱讀

    NIOSII那些事兒REV7.0

    NIOSII那些事兒REV7.0
    發表于 03-07 11:54

    mos管的那些事兒分享!

    通俗易懂,百度上要下載券,我直接在其他網站下了,在這里發出來,備用。MOS管的那些事兒.rar (1.33 MB )
    發表于 08-28 00:43

    CPU緩存對性能的影響

      說到CPU,不得不說的就是CPU緩存,目前CPU緩存已經成了衡量CPU性能的一個必要指標,
    發表于 11-13 17:58 ?2491次閱讀

    電源選型的那些事兒

    電路教程相關知識的資料,關于電源選型的那些事兒
    發表于 10-10 14:34 ?0次下載

    Linux那些事兒linux的入門介紹

    電子發燒友網站提供《Linux那些事兒linux的入門介紹.pdf》資料免費下載
    發表于 05-02 08:00 ?4次下載

    Linux的那些事兒之我是Sysfs

    Linux的那些事兒之我是Sysfs
    發表于 10-29 09:28 ?5次下載
    Linux的<b class='flag-5'>那些</b><b class='flag-5'>事兒</b>之我是Sysfs

    Linux的那些事兒之我是SCSI硬盤

    Linux的那些事兒之我是SCSI硬盤
    發表于 10-29 09:32 ?19次下載
    Linux的<b class='flag-5'>那些</b><b class='flag-5'>事兒</b>之我是SCSI硬盤

    Linux的那些事兒之我是PCI

    Linux的那些事兒之我是PCI
    發表于 10-29 09:35 ?10次下載
    Linux的<b class='flag-5'>那些</b><b class='flag-5'>事兒</b>之我是PCI

    Linux的那些事兒之我是Hub

    Linux的那些事兒之我是Hub
    發表于 10-29 09:37 ?7次下載
    Linux的<b class='flag-5'>那些</b><b class='flag-5'>事兒</b>之我是Hub

    Linux的那些事兒之我是Block層

    Linux的那些事兒之我是Block層
    發表于 10-29 09:43 ?9次下載
    Linux的<b class='flag-5'>那些</b><b class='flag-5'>事兒</b>之我是Block層

    CPU緩存是什么意思_CPU緩存有什么作用

    由于處理器是核心硬件,相信我們在選擇處理器的時候都會去關心處理器參數方面,而在處理器核心參數中,我們經常會看到緩存(Cache)這個參數,那么CPU緩存有什么作用呢?下面小編科普一下關于CP
    發表于 05-19 09:24 ?7657次閱讀

    緩存如何工作,如何設計CPU緩存

    20世紀80年代,CPU性能有了顯著提升,但這受到板載內存訪問速度緩慢增長的阻礙。隨著這種差異的惡化,工程師們發現了一種通過新的設計技術緩存來解決問題的方法。本文將幫助你進一步了解什么是緩存,它如何工作以及如何設計
    的頭像 發表于 11-19 17:23 ?2752次閱讀

    CPU緩存的作用及原理有哪些

    CPU緩存是位于CPU與內存之間的臨時存儲器,它的容量比內存小很多,但交換速度比內存要快很多。 CPU緩存分為三類:一級
    的頭像 發表于 08-27 15:58 ?1.1w次閱讀

    MOS管的那些事兒.課件下載

    MOS管的那些事兒.課件下載
    發表于 12-06 15:14 ?0次下載
    主站蜘蛛池模板: 国产中文在线| 人人听力网mp3下载| 探花口爆颜射乳交日韩| 国产精品AV无码免费播放| 驯服有夫之妇HD中字日本| 精品淑女少妇AV久久免费| 99久久精品免费看国产一区二区三区 | 秋霞伦理机在线看片| 国产福利高清在线视频| 亚洲一区精品在线| 嗯啊…嗯np男男双性总受| 国产精品高清在线观看地址| 一点色成人| 日本午夜视频在线| 精品香蕉99久久久久网站| bt成人种子| 亚洲精品无码成人AAA片| 女子初尝黑人巨嗷嗷叫| 国产麻豆AV伦| jk制服啪啪网站| 亚洲 天堂 欧美 日韩 国产| 美女拉开腿让男生桶到爽| 国产精品久久久久影院嫩草| 100国产精品人妻无码| 天天射天天爱天天干| 免费毛片a在线观看67194| 国产亚洲人成在线视频| 99久久就热视频精品草| 亚洲成熟人网站| 日本漫画大全无翼乌| 久久学生精品国产自在拍| 国产福利一区二区精品| 97免费人妻在线观看| 亚洲精品国产精品精| 日本孕妇大胆孕交| 毛片免费观看| 护士喂我吃乳液我脱她内裤| 粉嫩AV国产一区二区福利姬| 做暖暖视频在线看片免费| 性女传奇 快播| 日韩欧美精品有码在线播放免费|