在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

深入理解CACHE VIPT與PIPT的工作原理

冬至子 ? 來源:Linux與SoC ? 作者:linux-soc ? 2023-06-05 14:56 ? 次閱讀

啟動(dòng)信息描述

內(nèi)核啟動(dòng)過程中有如下打印信息:

CPU: PIPT / VIPT nonaliasing data cache, VIPT nonaliasing instruction cache

這行打印信息代表了處理器L1 CACHE所支持的尋址方式。

在kernel啟動(dòng)過程中,雖然這里第一次出現(xiàn)CACHE相關(guān)的打印信息,但是,此處并不是kernel第一次操作CACHE。

例如:對(duì)于zImage而言,解壓縮過程中會(huì)開啟CACHE并配置CACHE 寫屬性。

#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
#define CB_BITS 0x08
#else
#define CB_BITS 0x0c
#endif

CPU初始化的匯編文件head.S中,會(huì)根據(jù)kernel配置來使能CACHE。

#ifdef CONFIG_CPU_DCACHE_DISABLE
        bic     r0, r0, #CR_C
#endif
#ifdef CONFIG_CPU_BPREDICT_DISABLE
        bic     r0, r0, #CR_Z
#endif
#ifdef CONFIG_CPU_ICACHE_DISABLE
        bic     r0, r0, #CR_I
#endif

代碼分析

以上打印信息源自于 kernel 代碼的setup.c中。

static void __init cacheid_init(void)
{
 unsigned int arch = cpu_architecture();

 if (arch >= CPU_ARCH_ARMv6) {
  unsigned int cachetype = read_cpuid_cachetype();

  if ((arch == CPU_ARCH_ARMv7M) && !(cachetype & 0xf000f)) {
   cacheid = 0;
  } else if ((cachetype & (7 < < 29)) == 4 < < 29) {
   /* ARMv7 register format */
   arch = CPU_ARCH_ARMv7;
   cacheid = CACHEID_VIPT_NONALIASING;
   switch (cachetype & (3 < < 14)) {
   case (1 < < 14):
    cacheid |= CACHEID_ASID_TAGGED;
    break;
   case (3 < < 14):
    cacheid |= CACHEID_PIPT;
    break;
   }
  } else {
   arch = CPU_ARCH_ARMv6;
   if (cachetype & (1 < < 23))
    cacheid = CACHEID_VIPT_ALIASING;
   else
    cacheid = CACHEID_VIPT_NONALIASING;
  }
  if (cpu_has_aliasing_icache(arch))
   cacheid |= CACHEID_VIPT_I_ALIASING;
 } else {
  cacheid = CACHEID_VIVT;
 }

 pr_info("CPU: %s data cache, %s instruction cache\\n",
  cache_is_vivt() ? "VIVT" :
  cache_is_vipt_aliasing() ? "VIPT aliasing" :
  cache_is_vipt_nonaliasing() ? "PIPT / VIPT nonaliasing" : "unknown",
  cache_is_vivt() ? "VIVT" :
  icache_is_vivt_asid_tagged() ? "VIVT ASID tagged" :
  icache_is_vipt_aliasing() ? "VIPT aliasing" :
  icache_is_pipt() ? "PIPT" :
  cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown");
}

首先,通過cpu_architecture()獲取處理器內(nèi)核版本號(hào)

int __pure cpu_architecture(void)
{
 BUG_ON(__cpu_architecture == CPU_ARCH_UNKNOWN);

 return __cpu_architecture;
}

處理器內(nèi)核版本號(hào)通過數(shù)據(jù)結(jié)構(gòu)proc_arch來維護(hù),數(shù)據(jù)結(jié)構(gòu)成員的值代表的ARM-vXXX

static const char *proc_arch[] = {
 "undefined/unknown",
 "3",
 "4",
 "4T",
 "5",
 "5T",
 "5TE",
 "5TEJ",
 "6TEJ",
 "7",
 "7M",
 "?(12)",
 "?(13)",
 "?(14)",
 "?(15)",
 "?(16)",
 "?(17)",
};

處理器內(nèi)核版本編號(hào)如下,例如__cpu_architecture為4則代表的是ARM-v5內(nèi)核。

#define CPU_ARCH_UNKNOWN 0
#define CPU_ARCH_ARMv3  1
#define CPU_ARCH_ARMv4  2
#define CPU_ARCH_ARMv4T  3
#define CPU_ARCH_ARMv5  4
#define CPU_ARCH_ARMv5T  5
#define CPU_ARCH_ARMv5TE 6
#define CPU_ARCH_ARMv5TEJ 7
#define CPU_ARCH_ARMv6  8
#define CPU_ARCH_ARMv7  9
#define CPU_ARCH_ARMv7M  10

需要注意的是,這里獲取處理器內(nèi)核版本號(hào),不是通過讀取MIDR寄存器來實(shí)現(xiàn)的。

針對(duì)具體的ARM內(nèi)核版本,獲取CACHE所支持的尋址方式,并據(jù)此初始化cacheid。后面以cacheid為依據(jù)對(duì)CACHE的所支持的尋址方式進(jìn)行分類。

在ARM處理器內(nèi)部包含了CACHE類型信息的只讀寄存器,這在芯片設(shè)計(jì)初期便已經(jīng)定義好,后期無法修改。在這個(gè)寄存器中包含了CACHE的尋址策略。對(duì)于ARM v系列的處理器內(nèi)核而言,獲取CACHE類型的指令代碼如下:

#define read_cpuid(reg)       \\
 ({        \\
  unsigned int __val;     \\
  asm("mrc p15, 0, %0, c0, c0, " __stringify(reg) \\
      : "=r" (__val)     \\
      :       \\
      : "cc");      \\
  __val;       \\
 })

基于讀取CACHE類型寄存器得到信息來初始化cacheid,利用cachetype.h中定義的宏,打印出cache類型。

基于cacheid定義了如下的宏定義:

#define cache_is_vivt()   cacheid_is(CACHEID_VIVT)
#define cache_is_vipt()   cacheid_is(CACHEID_VIPT)
#define cache_is_vipt_nonaliasing() cacheid_is(CACHEID_VIPT_NONALIASING)
#define cache_is_vipt_aliasing() cacheid_is(CACHEID_VIPT_ALIASING)
#define icache_is_vivt_asid_tagged() cacheid_is(CACHEID_ASID_TAGGED)
#define icache_is_vipt_aliasing() cacheid_is(CACHEID_VIPT_I_ALIASING)
#define icache_is_pipt()  cacheid_is(CACHEID_PIPT)
...
static inline unsigned int __attribute__((pure)) cacheid_is(unsigned int mask)
{
 return (__CACHEID_ALWAYS & mask) |
        (~__CACHEID_NEVER & __CACHEID_ARCH_MIN & mask & cacheid);
}

而本文開頭中打印出來的信息,就是基于上面這些宏得出的結(jié)果。

從kenrel啟動(dòng)的日志信息中可以看出,當(dāng)前CPU內(nèi)核的CACHE類型如下:

DCACHE

PIPT / VIPT nonaliasing

ICACHE

VIPT nonaliasing

ARM處理器不同內(nèi)核版本的CACHE類型如下:

圖片

通常來說,CACHE得尋址類型包括VIPT、PIPT、VIVT,而本文重點(diǎn)分析得是VIPT以及PIPT的工作原理

VIPT和PIPT

具備MMU(TLB)、CACHE的ARM處理器,其地址翻譯的流程如下:

圖片

那么上圖中紅框內(nèi)的CACHE部分,根據(jù)索引標(biāo)簽對(duì)應(yīng)的是物理地址還是虛擬地址,將CACHE的尋址方式分為VIPT CACHE和PIPT CACHE。

VI的含義是使用虛擬地址來構(gòu)建緩存索引(index)。反之,PI的含義是使用物理地址來構(gòu)建緩存索引。

緩存索引用于從緩存中提取標(biāo)記,將它與從物理地址計(jì)算的緩存標(biāo)記比對(duì)。如果匹配,則緩存中命中該查找,從緩存中提取相關(guān)的數(shù)據(jù)。否則,將從下一層緩存(或從內(nèi)存)中提取。

PT的含義是使用物理地址來構(gòu)建緩存標(biāo)記(tag),之所以使用PT作為CACHE查找索引是為了解決VIVT中存在的索引沖突,即兩個(gè)進(jìn)程可以為不同的物理地址使用相同的虛擬地址。

VIPT

VIPT CACHE使用物理地址作為Tag,邏輯地址作為Index。通過Index查詢CACHE獲取到物理地址中的tag部分。同時(shí)呢,利用邏輯地址去查TLB,在TLB中獲取到物理地址。然后將CACHE中查詢到的物理地址Tag部分,同TLB中獲取到的物理地址Tag部分作比較。若二者相同,則CACHE hit,否則CACHE miss。

圖片

aliasing

對(duì)于VIPT CACHE而言,下面代碼中的virtual_addr_A和virtual_addr_B雖然不同,但是它們指向了同一個(gè)物理地址PA。

mmap(virtual_addr_A,4096,prot,flags,file_descriptor,offset)
mmap(virtual_addr_B,4096,prot,flags,file_descriptor,offset)

VIPT使用虛擬地址作為CACHE Index,因此物理地址A的數(shù)據(jù)在CACHE中有兩份,分別由virtual_addr_A和virtual_addr_B進(jìn)行管理。這樣的情形稱之為CACHE 別名。

圖片

可以通過下面的4種方法來避免別名問題帶來的影響:

1.當(dāng)進(jìn)行內(nèi)存數(shù)據(jù)更新時(shí)進(jìn)行cache invalid操作

  1. 多副本數(shù)據(jù)同步更新

以上兩種方法需要進(jìn)程通過虛實(shí)地址轉(zhuǎn)換等操作,獲取到是否有副本數(shù)據(jù)存在這樣的信息。而VIPT的設(shè)計(jì)初衷是避免虛實(shí)地址轉(zhuǎn)換,因此,這兩種方法并不是非常可取。

  1. 縮小CACHE size

假設(shè)對(duì)于一個(gè)32bit位寬的虛擬地址而言,他的page offset為12bit。若CACHE size小于4K則不會(huì)產(chǎn)生別名問題,假設(shè)CACHE size大于4K,則會(huì)產(chǎn)生別名問題。但是CACHE過小,cache miss又會(huì)大幅增加。

圖片

  1. page color或者cache cloring

若以上3種方法都沒有解決CACHE別名問題,那么可以使用緩存著色的方法。

PIPT

PIPT中的tag和index均為物理地址。而CPU發(fā)出的邏輯地址也稱之為虛擬地址,因此,首先需要通過TLB或查詢內(nèi)存中的頁(yè)表,將邏輯地址轉(zhuǎn)換為對(duì)應(yīng)的物理地址。再進(jìn)行CACHE緩存查找。索引和標(biāo)簽都使用物理地址。雖然這很簡(jiǎn)單,避免了重名問題,但速度也很慢,因?yàn)楸仨毾炔檎椅锢淼刂?這可能涉及TLB丟失和訪問主內(nèi)存),才能在緩存中查找該地址。

圖片

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 處理器
    +關(guān)注

    關(guān)注

    68

    文章

    19825

    瀏覽量

    233779
  • ARM
    ARM
    +關(guān)注

    關(guān)注

    134

    文章

    9321

    瀏覽量

    375466
  • 寄存器
    +關(guān)注

    關(guān)注

    31

    文章

    5425

    瀏覽量

    123559
  • LINUX內(nèi)核
    +關(guān)注

    關(guān)注

    1

    文章

    317

    瀏覽量

    22237
  • cache技術(shù)
    +關(guān)注

    關(guān)注

    0

    文章

    41

    瀏覽量

    1201
收藏 人收藏

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    深入理解運(yùn)放的工作原理(空氣凈化器系統(tǒng)案例)

    重點(diǎn)講解了運(yùn)放的內(nèi)部電路結(jié)構(gòu),幫助深入理解運(yùn)放的工作原理。運(yùn)放是設(shè)計(jì)使用非常頻繁且非常重要器件,通常在信號(hào)放大,電流采樣電路里常見,對(duì)于初學(xué)者經(jīng)常感到困惑,所以掌握好能夠幫助你很好的分析電路。
    的頭像 發(fā)表于 04-19 09:10 ?6495次閱讀

    深入理解運(yùn)放的工作原理內(nèi)部電路結(jié)構(gòu)

    重點(diǎn)講解了運(yùn)放的內(nèi)部電路結(jié)構(gòu),幫助深入理解運(yùn)放的工作原理。運(yùn)放是設(shè)計(jì)使用非常頻繁且非常重要器件,通常在信號(hào)放大,電流采樣電路里常見。
    的頭像 發(fā)表于 04-22 16:02 ?1.8w次閱讀
    <b class='flag-5'>深入理解</b>運(yùn)放的<b class='flag-5'>工作原理</b>內(nèi)部電路結(jié)構(gòu)

    深入理解Android

    深入理解Android
    發(fā)表于 08-20 15:30

    深入理解和實(shí)現(xiàn)RTOS_連載

    和trcohili的帖子。深入理解和實(shí)現(xiàn)RTOS_連載1_RTOS的前生今世今天發(fā)布的是第一篇,"RTOS的前生今世"。通過軟件系統(tǒng)結(jié)構(gòu)的比對(duì)簡(jiǎn)要的介紹rtos為何而生。如果讀者對(duì)RTOS
    發(fā)表于 05-29 11:20

    深入理解和實(shí)現(xiàn)RTOS_連載

    和trcohili的帖子。trochili rtos完全是作者興趣所在,且行且堅(jiān)持,比沒有duo。深入理解和實(shí)現(xiàn)RTOS_連載1_RTOS的前生今世今天發(fā)布的是第一篇,"RTOS的前生今世"
    發(fā)表于 05-30 01:02

    深入理解lte-a

    深入理解LTE-A
    發(fā)表于 02-26 10:21

    深入理解STM32

    時(shí)鐘系統(tǒng)是處理器的核心,所以在學(xué)習(xí)STM32所有外設(shè)之前,認(rèn)真學(xué)習(xí)時(shí)鐘系統(tǒng)是必要的,有助于深入理解STM32。下面是從網(wǎng)上找的一個(gè)STM32時(shí)鐘框圖,比《STM32中文參考手冊(cè)》里面的是中途看起來清晰一些:重要的時(shí)鐘:PLLCLK,SYSCLK,HCKL,PCLK1,...
    發(fā)表于 08-12 07:46

    對(duì)棧的深入理解

    為什么要深入理解棧?做C語言開發(fā)如果棧設(shè)置不合理或者使用不對(duì),棧就會(huì)溢出,溢出就會(huì)遇到無法預(yù)測(cè)亂飛現(xiàn)象。所以對(duì)棧的深入理解是非常重要的。注:動(dòng)畫如果看不清楚可以電腦看更清晰啥是棧先來看一段動(dòng)畫:沒有
    發(fā)表于 02-15 07:01

    為什么要深入理解

    [導(dǎo)讀] 從這篇文章開始,將會(huì)不定期更新關(guān)于嵌入式C語言編程相關(guān)的個(gè)人認(rèn)為比較重要的知識(shí)點(diǎn),或者踩過的坑。為什么要深入理解棧?做C語言開發(fā)如果棧設(shè)置不合理或者使用不對(duì),棧就會(huì)溢出,溢出就會(huì)遇到無法
    發(fā)表于 02-15 06:09

    深入理解Android之資源文件

    深入理解Android之資源文件
    發(fā)表于 01-22 21:11 ?22次下載

    深入理解Android》文前

    深入理解Android》文前
    發(fā)表于 03-19 11:23 ?0次下載

    深入理解Android:卷I》

    深入理解Android:卷I》
    發(fā)表于 03-19 11:23 ?0次下載

    深入理解Android網(wǎng)絡(luò)編程

    深入理解Android網(wǎng)絡(luò)編程
    發(fā)表于 03-19 11:26 ?1次下載

    深入理解MOS管電子版資源下載

    深入理解MOS管電子版資源下載
    發(fā)表于 07-09 09:43 ?0次下載

    深入理解Cache工作原理

    按照數(shù)據(jù)關(guān)系劃分:Inclusive/exclusive Cache: 下級(jí)Cache包含上級(jí)的數(shù)據(jù)叫inclusive Cache。不包含叫exclusive Cache。舉個(gè)例子,
    的頭像 發(fā)表于 05-30 16:02 ?1074次閱讀
    <b class='flag-5'>深入理解</b><b class='flag-5'>Cache</b><b class='flag-5'>工作原理</b>
    主站蜘蛛池模板: 男女www视频在线看网站 | 午夜久久久久久亚洲国产精品 | 好大好紧好爽好湿润视频 | 555成人免费影院 | 日本h片在线观看 | 欧美成人免费观看bbb | 日日干天天干 | 一区二区免费 | www色.com| 性生大片免费观看无遮挡 | 手机成人在线视频 | 美女张开腿让男生桶出水 | 国产玖玖 | 色婷婷狠狠 | 欧美特级午夜一区二区三区 | 免费在线观看的视频 | 四虎影库在线播放 | 亚洲午夜久久久久久噜噜噜 | 日本www色视频 | 永久黄网站色视频免费观看99 | 色偷偷亚洲天堂 | 午夜影视啪啪免费体验区深夜 | 久久美女免费视频 | 国产精品资源手机在线播放 | 国产亚洲欧美一区 | 亚洲精品aaa揭晓 | 日本一道高清不卡免费 | 永久看日本大片免费 | 午夜免费福利片观看 | 午夜精品久久久久 | you ji z z日本人在线观看 | 亚洲 [12p]| 黄色一级a毛片 | 亚洲精品老司机综合影院 | 俺来色| 女人本色高清在线观看wwwwww国产 | 夜夜夜夜夜夜夜工噜噜噜 | 成人午夜久久 | 亚洲天堂视频在线播放 | 西西人体大胆高清啪啪欧洲 | 手机看片1024在线观看 |