自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

八張圖講清楚Mmap實(shí)現(xiàn)原理

開(kāi)發(fā) 前端
Linux缺頁(yè)中斷是指當(dāng)進(jìn)程訪問(wèn)尚未建立映射關(guān)系的虛擬內(nèi)存時(shí),系統(tǒng)會(huì)觸發(fā)缺頁(yè)中斷,并根據(jù)頁(yè)面的狀態(tài)來(lái)分配物理頁(yè)面并建立映射關(guān)系。

大家好,最近在研究Linux內(nèi)核以及Linux系統(tǒng)編程的時(shí)候,經(jīng)常會(huì)碰到mmap內(nèi)存映射,mmap函數(shù)是實(shí)現(xiàn)高性能編程的一個(gè)關(guān)鍵點(diǎn),下面我通過(guò)幾張圖詳細(xì)介紹一下mmap實(shí)現(xiàn)原理。

(本文以64位CPU為原型講解)

1.虛擬地址如何映射物理地址?

要了解mmap實(shí)現(xiàn)原理,首先必須了解虛擬地址如何映射物理地址,如果沒(méi)掌握這個(gè)知識(shí)點(diǎn),后續(xù)閱讀會(huì)有很大的困難,切記!

虛擬地址映射物理地址采用的是頁(yè)表機(jī)制,64位CPU采用的是4級(jí)頁(yè)表。

圖片圖片

64位CPU虛擬地址長(zhǎng)度為64位,但實(shí)際只用48位就已滿足虛擬地址映射物理內(nèi)存的要求,如下圖:

圖片圖片

64位CPU地址空間可分為三個(gè)部分:

  • 128T用戶空間
  • 128T內(nèi)核空間
  • 其他:保留空間

用戶空間和內(nèi)核空間共256T,2的48次方剛好為256T,所以48位地址空間能映射所有的虛擬地址。

48位虛擬地址由五部分組成:

  • pgd表偏移,四級(jí)表,9位
  • pud表偏移,三級(jí)表,9位
  • pmd表偏移,二級(jí)表,9位
  • ptl表偏移,一級(jí)表,9位
  • 物理頁(yè)偏移,12位

問(wèn)題1:為什么pgd,pud,pmd,ptl表偏移是9位?

pgd,pud,pmd,ptl表實(shí)現(xiàn)原理都相同,我們以pgd來(lái)講解。

一張pgd表對(duì)應(yīng)一個(gè)物理頁(yè),一個(gè)物理頁(yè)的大小為4KB,一個(gè)pgd_t表項(xiàng)為8個(gè)字節(jié),一張pgd表能存儲(chǔ)4*1024/8=512個(gè)表項(xiàng)。

2的9次方等于512,所以采用9位的表偏移就能索引整張表的表項(xiàng)。

圖片圖片

問(wèn)題2:為什么物理頁(yè)偏移為12位?

一個(gè)物理頁(yè)為4KB,物理頁(yè)訪問(wèn)是單字節(jié)訪問(wèn),2的12次方剛好為4KB,所以物理頁(yè)偏移為12位。

1.1 虛擬地址映射物理地址過(guò)程

虛擬地址映射物理地址需要依次索引pgd,pud,pmd,ptl表,具體過(guò)程如下:

  • 步驟1:查詢pgd表

查詢pgd表,首先需要找到pgd表物理頁(yè)首地址,pgd表物理頁(yè)首地址由task_struct->mm_struct->pgd成員保存,每個(gè)進(jìn)程的task_struct->mm_struct->pgd成員數(shù)值不同,所以不同的進(jìn)程即使使用相同的虛擬地址也不會(huì)訪問(wèn)相同到物理地址。

通過(guò)pgd表首地址+虛擬地址pgd表偏移索引到pgd_t表項(xiàng)完成pgd表查詢。

  • 步驟2:查詢pud表

pgd_t表項(xiàng)存儲(chǔ)的是pud表物理頁(yè)首地址。

通過(guò)pud表首地址+虛擬地址pud表偏移索引到pud_t表項(xiàng)完成pud表查詢。

  • 步驟3:查詢pmd表

pud_t表項(xiàng)存儲(chǔ)的是pmd表物理頁(yè)首地址。

通過(guò)pmd表首地址+虛擬地址pmd表偏移索引到pmd_t表項(xiàng)完成pmd表查詢。

  • 步驟4:查詢ptl表

pmd_t表項(xiàng)存儲(chǔ)的是ptl表物理頁(yè)首地址。

通過(guò)ptl表首地址+虛擬地址ptl表偏移索引到pte表項(xiàng)完成ptl表查詢。

  • 步驟5:映射物理地址

pte表項(xiàng)存儲(chǔ)的是物理頁(yè)首地址,pte+虛擬地址物理頁(yè)偏移就能定位到物理地址。

注意:定位到物理地址后,虛擬地址映射物理地址的過(guò)程就已完成。

思考:64位CPU頁(yè)表機(jī)制需要多少?gòu)埍恚?nbsp;

圖片圖片

表的數(shù)量如下:

  • pgd表1張,占用內(nèi)存4KB。
  • pud表2的9次方張,占用內(nèi)存4KB * 512 = 2MB。
  • pmd表2的18次方張,占用內(nèi)存4KB * 512 * 512 = 1GB。
  • ptl表2的27次方張,占用內(nèi)存4KB * 512 * 512 * 512 = 512GB。

如果每張表都固定分配一個(gè)物理頁(yè),所有的表占用的內(nèi)存空間已經(jīng)達(dá)到500多GB,這只是一個(gè)進(jìn)程占用的空間,如果有大量的進(jìn)程,占用內(nèi)存就非??植懒?。

通常情況下,進(jìn)程只會(huì)使用很小的內(nèi)存,所以系統(tǒng)不會(huì)一下把所有的頁(yè)表都創(chuàng)建出來(lái),而是采用動(dòng)態(tài)分配的方式創(chuàng)建,當(dāng)需要訪問(wèn)虛擬地址時(shí),通過(guò)缺頁(yè)中斷創(chuàng)建虛擬地址對(duì)應(yīng)的各個(gè)頁(yè)表。

2.mmap實(shí)現(xiàn)原理

mmap函數(shù)是一種內(nèi)存映射文件的方法,它可以將一個(gè)文件或設(shè)備映射到進(jìn)程的地址空間中,使得進(jìn)程可以像訪問(wèn)內(nèi)存一樣訪問(wèn)文件或設(shè)備。

mmap可以分為:文件映射和匿名映射。

mmap函數(shù)主要工作就是創(chuàng)建VMA。

2.1 VMA簡(jiǎn)介

VMA(Virtual Memory Area,虛擬內(nèi)存區(qū)域)是Linux內(nèi)核中用于管理進(jìn)程虛擬內(nèi)存的數(shù)據(jù)結(jié)構(gòu)。每個(gè)進(jìn)程都有一個(gè)VMA鏈表,用于描述進(jìn)程的虛擬地址空間的不同區(qū)域。

VMA包含了一段連續(xù)的虛擬地址空間,它定義了該區(qū)域的起始地址、結(jié)束地址以及一些屬性信息。VMA可以表示進(jìn)程的代碼段、數(shù)據(jù)段、堆、棧等不同的內(nèi)存區(qū)域。

VMA對(duì)應(yīng)Linux內(nèi)核struct vm_area_struct對(duì)象。

注意:VMA用于指導(dǎo)虛擬內(nèi)存映射物理內(nèi)存,沒(méi)有VMA指導(dǎo)無(wú)法完成虛擬地址和物理地址映射。

圖片圖片

struct vm_area_struct結(jié)構(gòu)體主要成員如下:

  • vm_start:虛擬內(nèi)存區(qū)域起始地址。
  • vm_end:虛擬內(nèi)存區(qū)域結(jié)束地址,vm_end減去vm_start為映射區(qū)域長(zhǎng)度。
  • vm_page_prot:虛擬內(nèi)存訪問(wèn)權(quán)限,

PROT_READ:可讀

PROT_WRITE:可寫(xiě)

PROT_EXEC:可執(zhí)行

  • vm_page_flags:內(nèi)存映射標(biāo)志,

MAP_SHARED:共享映射

MAP_PRIVATE:私有映射

  • vm_ops:文件映射操作集合,匿名映射為NULL。
  • vm_pgoff:文件映射文件偏移量,匿名映射無(wú)效。
  • vm_file:映射文件,匿名映射為NULL。

3.缺頁(yè)中斷

Linux缺頁(yè)中斷是指當(dāng)進(jìn)程訪問(wèn)尚未建立映射關(guān)系的虛擬內(nèi)存時(shí),系統(tǒng)會(huì)觸發(fā)缺頁(yè)中斷,并根據(jù)頁(yè)面的狀態(tài)來(lái)分配物理頁(yè)面并建立映射關(guān)系。

通過(guò)mmap創(chuàng)建VMA后,我們使用VMA內(nèi)存映射區(qū)虛擬地址,但此時(shí)虛擬地址不能映射物理地址,原因是映射表還沒(méi)有動(dòng)態(tài)創(chuàng)建出來(lái)。

圖片圖片

當(dāng)缺頁(yè)中斷發(fā)生后,中斷處理函數(shù)會(huì)完成虛擬地址至物理地址各映射表創(chuàng)建。

各映射表的創(chuàng)建需要task_struct->mm_struct->pgd和虛擬地址表偏移量共同完成。

完成映射表創(chuàng)建后,還有最后一步工作需要完成,那就是pte創(chuàng)建。

pte該如何創(chuàng)建呢?

我們接著往下看...

4.文件映射

文件映射可以將文件的內(nèi)容映射到進(jìn)程的內(nèi)存空間。

文件映射pte指向文件的物理內(nèi)存頁(yè),文件映射需要VMA指向?qū)?yīng)的文件,由文件來(lái)生成物理頁(yè)。

圖片圖片

mmap函數(shù)實(shí)現(xiàn)文件映射時(shí)需指定文件fd,文件偏移量,文件映射長(zhǎng)度。

內(nèi)核會(huì)根據(jù)文件fd,文件偏移量,文件映射長(zhǎng)度填充新創(chuàng)建的VMA。

文件映射創(chuàng)建pte時(shí)根據(jù)VMA記錄的文件file,文件偏移量,文件映射長(zhǎng)度定位到具體文件以及文件偏移位置,將磁盤(pán)文件內(nèi)容拷貝至物理內(nèi)存頁(yè),再將物理內(nèi)存頁(yè)轉(zhuǎn)換成pte設(shè)置進(jìn)ptl表。

至此文件映射已完成,就能通過(guò)虛擬地址訪問(wèn)文件物理內(nèi)存頁(yè)。

5.匿名映射

圖片圖片

匿名映射相對(duì)來(lái)說(shuō)比較簡(jiǎn)單,只要在創(chuàng)建pte的時(shí)候,從物理內(nèi)存中申請(qǐng)一個(gè)物理內(nèi)存頁(yè),將物理內(nèi)存頁(yè)轉(zhuǎn)換成pte設(shè)置進(jìn)ptl表,就完成匿名映射。

責(zé)任編輯:武曉燕 來(lái)源: 物聯(lián)網(wǎng)心球
相關(guān)推薦

2024-02-22 12:20:23

Linux零拷貝技術(shù)

2021-04-21 10:00:08

MySQL索引數(shù)據(jù)庫(kù)

2020-07-29 09:21:34

Docker集群部署隔離環(huán)境

2021-07-05 22:22:24

協(xié)議MQTT

2024-07-01 13:45:18

2025-02-10 08:55:47

2019-07-07 08:18:10

MySQL索引數(shù)據(jù)庫(kù)

2022-01-05 09:27:24

讀擴(kuò)散寫(xiě)擴(kuò)散feed

2021-10-29 11:30:31

補(bǔ)碼二進(jìn)制反碼

2021-01-20 06:02:24

數(shù)據(jù)分析驅(qū)動(dòng)

2024-04-01 10:09:23

AutowiredSpring容器

2019-06-20 17:49:51

RPCHTTP協(xié)議

2017-12-17 20:17:23

NoSQLSQL數(shù)據(jù)

2018-08-13 09:20:21

NoSQLSQL數(shù)據(jù)

2021-12-06 07:15:47

Pulsar地域復(fù)制

2020-10-16 17:20:21

索引MySQL數(shù)據(jù)庫(kù)

2018-05-21 07:08:18

行為驅(qū)動(dòng)開(kāi)發(fā)BDD編碼

2020-12-24 15:18:27

大數(shù)據(jù)數(shù)據(jù)分析

2023-07-26 00:40:25

AI工具備忘錄

2021-04-10 10:37:04

OSITCP互聯(lián)網(wǎng)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)